Smart Billing App: Zero-Dependency Billing Software in Pure Python
What it is
Smart Billing App (github.com/Shivay00001/smart_billing_app) is a lean desktop billing and invoicing app written in Python — and the interesting engineering decision is in what it doesn't use. Where its sibling project (billing_app) builds on ttkbootstrap themes, matplotlib charts, and an HMAC licensing system, Smart Billing App runs on Python's standard library plus tkinter. Nothing else. No pip install step, no dependency tree, no version-pinning headaches.
The result is a self-contained offline billing tool — products, billing screen, reports, analytics, printing, and CSV export — that you can run on any machine with Python 3.10+ and tkinter, including machines that will never see the internet.
The problem it solves
Dependency rot is a real deployment cost. Every third-party package you add is a future breakage: a yanked release, a dropped wheel for your platform, a conflict with the shop's aging Windows machine. For the target user — a single counter in a small shop — "pip install six packages" is already a support ticket. Smart Billing App's answer is radical simplicity: if it's in the Python standard library, it ships; if it isn't, it doesn't get used. tkinter ships with Python. SQLite ships with Python. csv, datetime, sqlite3 — all stdlib. The entire dependency story is one line: bring Python.
How it works: architecture
The repo (~300 KB) has a flat, readable layout:
smart_billing_app/
├── main.py # entry point + boot diagnostics
├── database.py # DatabaseManager (SQLite)
├── config.py # app configuration
├── core/
│ ├── analytics.py # sales analytics (stdlib only)
│ ├── exporter.py # CSV export
│ └── printing.py # receipt printing
├── ui/
│ ├── main_window.py # root window, screen routing
│ ├── billing_screen.py # point-of-sale screen
│ ├── dashboard_screen.py
│ ├── products_screen.py
│ ├── reports_screen.py
│ ├── settings_screen.py
│ └── styles.py # hand-rolled theming (no ttkbootstrap)
├── tests/test_smoke.py # DatabaseManager CRUD smoke test
├── build_app.py / build_debug.py
├── Dockerfile / docker-compose.yml
└── .github/workflows/deploy.yml
The entry point that diagnoses itself
main.py is more careful than most app entry points, and it's worth reading because it solves the #1 problem with desktop apps given to non-technical users: silent failure. Every boot stage is logged with a timestamp to startup_debug.txt:
LOG_FILE = "startup_debug.txt"
def log(msg):
timestamp = datetime.datetime.now().strftime("%H:%M:%S")
with open(LOG_FILE, "a") as f:
f.write(f"[{timestamp}] {msg}\n")
The sequence: clear the old log → import tkinter → import DatabaseManager → import MainWindow → initialize the database → create the window → run the mainloop. If any import fails, the error is written to the log and shown in a fallback messagebox that names the log file. If a runtime crash happens later, the full traceback goes to the log and the user gets a dialog pointing at it. This is the kind of defensive bootstrapping you write after supporting real users on real machines.
Database layer
database.py holds DatabaseManager, which opens (creating if needed) a local SQLite file next to the app. The smoke test (tests/test_smoke.py) exercises it against a temp database: initialize, insert a product row, read it back, assert. The products table carries name, price, category, stock_quantity — the essentials for a counter app.
Screens and core modules
ui/main_window.py is the root window and screen router. The screens are single-purpose modules: billing_screen.py (~10.8 KB) is the POS flow, products_screen.py (~8.9 KB) inventory management, dashboard_screen.py the overview, reports_screen.py reports, settings_screen.py configuration, and styles.py is hand-rolled theming — doing in raw tkinter what ttkbootstrap would do elsewhere, which is precisely the point of the zero-dependency constraint.
core/ holds the business capabilities as independent modules: analytics.py (~3.2 KB) computes sales analytics without numpy/pandas (pure stdlib aggregation), exporter.py (~2.6 KB) writes CSV exports, and printing.py (~5.9 KB) handles receipt output.
How to run it
git clone https://github.com/Shivay00001/smart_billing_app.git
cd smart_billing_app
python main.py
That's it — no pip install at all. You need Python 3.10+ with tkinter and a display (on headless Linux it runs under xvfb-run; the README notes boot was verified on Python 3.12: database initializes, main window opens, no traceback). build_app.py handles packaging into a distributable.
Smart Billing App vs. Billing App: which one?
Same author, overlapping purpose — so here's the honest differentiation, based on reading both codebases:
| billing_app | smart_billing_app | |
|---|---|---|
| GUI stack | tkinter + ttkbootstrap ("cosmo" theme) | plain tkinter, hand-rolled styles |
| Dependencies | ttkbootstrap, matplotlib | stdlib + tkinter only |
| Licensing | HMAC offline licensing (TRIAL/PRO) | none — unrestricted |
| Data model | GST-aware (GSTIN, HSN/SAC, per-item GST rate) | simpler product model |
| PDF invoices | yes (reportlab-style generator) | no (CSV export + printing) |
| Boot diagnostics | basic | full timestamped startup_debug.txt logging |
| Best for | shops wanting a polished, sellable product | zero-setup deployment on any machine |
Think of it as two answers to the same problem at different points on the simplicity axis: billing_app is the professional product (licensing included, so someone can sell and support it), smart_billing_app is the austere one (runs anywhere Python runs, survives on machines where pip doesn't).
Screen-by-screen walkthrough
The UI is organized around the daily workflow of a billing counter:
ui/billing_screen.py(~10.8 KB) — the POS screen: pick products, set quantities, see the running total, complete the sale. This is the module with the most interaction logic, since billing speed is the whole product.ui/products_screen.py(~8.9 KB) — product catalog management: names, prices, categories, stock quantities.ui/dashboard_screen.py(~5.6 KB) — the at-a-glance view: today's sales, top products, stock alerts.ui/reports_screen.py(~2 KB) — sales reports with period selection, feeding off the analytics core.ui/settings_screen.py(~6.9 KB) — business name, invoice numbering, tax defaults, printer configuration.ui/main_window.py(~3.8 KB) — the root window and screen router; deliberately thin, since screens are self-contained.ui/styles.py(~4.5 KB) — hand-rolled theming. This module exists because of the zero-dependency rule: everything ttkbootstrap would provide (consistent fonts, colors, widget styling) is implemented in raw tkinter. It's the clearest evidence of what the constraint costs — roughly 4.5 KB of code that a dependency would have absorbed — and what it buys: no theme engine to break.
The analytics and printing cores
core/analytics.py (~3.2 KB) computes sales summaries — daily totals, product rankings, category breakdowns — using pure stdlib aggregation over SQLite query results. No pandas, no numpy. For a single counter's data volumes this is genuinely fine: the dataset is thousands of rows, not millions, and sqlite3 itself does the heavy grouping via SQL. The design lesson: push aggregation into SQL, keep Python for presentation, and you never need a data library.
core/printing.py (~5.9 KB) handles receipt output — formatting the sale as a printable receipt and sending it to the configured printer. Receipt printing is one of those features that sounds trivial until you deal with thermal printers, paper widths, and encoding; having it as a dedicated, replaceable module is the right call.
core/exporter.py (~2.6 KB) writes CSV exports of sales and products — the accountant-friendly output. Between exports, printing, and on-screen reports, the "get my data out" story is complete without any third-party I/O library.
Configuration and the CI story
config.py (~406 bytes) holds app-level configuration — small because the settings screen persists most preferences to the database. The repo also ships Dockerfile + docker-compose.yml and a GitHub Actions workflow (.github/workflows/deploy.yml, ~400 bytes) — minimal but present, signaling the project is maintained with real release hygiene rather than zip-file distribution.
build_app.py and build_debug.py handle packaging into a distributable, with app.ico / app_icon.png for branding.
What the smoke test actually proves
tests/test_smoke.py is short — about 30 lines — but it tests the right thing. It creates a temporary SQLite database, initializes DatabaseManager against it, inserts a product row, reads it back, and asserts the values match. No test database to manage, no fixtures, no cleanup beyond deleting the temp file. It proves the single most important property of the app: the persistence layer works. For a billing app, everything else is presentation — if the database round-trip is sound, the product is sound. More projects should have a 30-line test that proves their core invariant instead of a 3,000-line suite that proves nothing.
Honest status
Status: working desktop application, boot-verified. The entry path, database CRUD, and screen modules are real and tested (the smoke test does actual inserts and selects on SQLite). Honest limitations: the feature set is narrower than billing_app — no PDF invoice generation, no licensing system, no GST-specific fields — and a couple of committed artifacts (heartbeat.txt, startup_debug.txt samples) are dev debris rather than product. The analytics are stdlib aggregation, so they're fine for a single counter but not for heavy historical analysis.
Roadmap-shaped gaps: PDF invoice output (the one feature shops ask for), GST fields in the data model, a packaging story beyond build_app.py (e.g., a Windows installer), and removing the committed debug artifacts from the repo.
Who should look at this
Developers: main.py is a compact, genuinely good reference for defensive desktop-app bootstrapping — timestamped boot logging, import-stage isolation, and traceback-to-log crash handling, all in ~90 lines of stdlib. Copy the pattern into your own desktop apps; your future support load will thank you. Business users: if your machine is old, offline, and you just need to bill — this runs with zero installation friction.
Frequently asked questions
What dependencies does it need?
None beyond Python 3.10+ and tkinter, which ships with Python. The database, CSV export, analytics, and printing are all standard library.
How do I run it?
Clone the repo and run python main.py. On headless Linux use xvfb-run. Watch startup_debug.txt for timestamped boot diagnostics if anything goes wrong.
How is it different from billing_app?
Smart Billing App is the zero-dependency sibling: simpler data model, no licensing system, no PDF generation, hand-rolled tkinter styling. billing_app is the fuller professional build with ttkbootstrap theming, GST fields, PDF invoices, and HMAC offline licensing.