A Python toolkit for reading, transforming, and emitting Quicken Interchange Format (QIF) data, with a lightweight Tk GUI for common workflows (convert, merge, probe). The codebase uses a typed, protocol‑driven data model so parsing and emission are decoupled from UI concerns. The ultimate goal of this project is to provide an easy mechanism for bulk updates to Quicken data using tables generated by ChatGPT
Status (2025‑09‑01): Active migration completed to a protocol‑based data model with wrappers (Q* classes). GUI “Viewers” use the new packages. Tests run on
pytestper the project’s Unit Test Policy.
-
Unified QIF parsing via a protocol adapter (controller layer) that returns typed model objects implementing the project’s interfaces.
-
Typed data model with clear interfaces and wrapper classes:
- Interfaces in
quicken_helper/data_model/interfaces(e.g.,IQuickenFile, enums, section flags). - Wrapper classes in
quicken_helper/data_model/q_wrapper(QAccount,QCategory,QTransaction,QSplit,QSecurity,QTag, andQuickenFile). - Parser/Emitter in
quicken_helper/data_model/qif_parsers_emitters(QIF‑specific parse/emit logic).
- Interfaces in
-
GUI Viewers (Tkinter) in
quicken_helper/gui_viewers:- Convert tab – QIF ⇄ CSV (Quicken Windows/Mac profiles included).
- Merge tab – Excel↔QIF matching workflow with normalization helpers.
- Probe tab – Inspect QDX/QIF artifacts for quick diagnostics and previews.
-
QIF emission back from the model (round‑trip capable for supported constructs).
-
Batteries‑included test suite (
pytest) following the project’s Unit Test Policy (independent, isolated, deterministic tests with clear failure messages).
quicken_helper/
controllers/
qif_loader.py # Unified parse; protocol adapter; helpers
data_model/
interfaces/ # I/Fs & enums (e.g., IQuickenFile, section flags)
q_wrapper/ # Q* wrappers (QAccount, QCategory, QTransaction, ...)
qif_parsers_emitters/ # QIF parser/emitter (parse_qif, emit)
gui_viewers/
app.py # Tk root wiring tabs (Convert/Merge/Probe)
convert_tab.py
merge_tab.py
probe_tab.py
csv_profiles.py # Quicken Windows/Mac CSV schema helpers
helpers.py | utils.py | scaling.py
tests/ # Pytest suite (controllers, data model, GUI harness)
Note: Some files have been relocated during the migration; current canonical locations are under
quicken_helper/*. Earlierqif_converter/qif_converter/gui/*paths were superseded where replacements exist.
Requires Python 3.10+ (recommended). Tkinter must be available for the GUI.
# 1) Clone the repo
git clone https://github.com/drmoisan/qif_converter.git
cd qif_converter
# 2) Create & activate a virtual environment (example: Windows PowerShell)
python -m venv .venv
. .venv/Scripts/Activate.ps1 # or: source .venv/bin/activate (macOS/Linux)
# 3) Install the project and dev dependencies (adjust as needed)
pip install -e .
# If you use a dev requirements file, also: pip install -r requirements-dev.txtpython -m quicken_helper.gui_viewers.app- Convert: Load a
.qif, pick a CSV profile (Quicken Windows/Mac), export. - Merge: Load QIF + Excel sources, auto‑match and refine, then apply/save.
- Probe: Open QIF/QDX to inspect headers, sections, and parsed artifacts.
Parse a QIF string into a typed QuickenFile (implements IQuickenFile), inspect, then re‑emit QIF:
from quicken_helper.data_model.qif_parsers_emitters.qif_file_parser_emitter import QifFileParserEmitter
with open("input.qif", "r", encoding="utf-8") as f:
text = f.read()
parser_emitter = QifFileParserEmitter()
qfile = parser_emitter.parse(text) # -> QuickenFile implementing IQuickenFile
# iterate transactions (shape defined by interfaces & wrappers)
for txn in qfile.transactions:
# e.g., print(txn.date, txn.amount, txn.payee)
pass
# round‑trip back to QIF (delegates to model’s emit implementation)
out_qif = qfile.emit_qif()Alternatively, use the controller to work with parsed transactions via a unified loader:
from quicken_helper.controllers.qif_loader import load_transactions_protocol
with open("input.qif", "r", encoding="utf-8") as f:
text = f.read()
txns = load_transactions_protocol(text) # iterable of transactions adhering to the protocolExact attributes/methods are governed by the interfaces in
quicken_helper/data_model/interfaces. See unit tests for canonical examples of expected shapes and behaviors.
We use pytest with a strict policy emphasizing independence, isolation, determinism, clarity, and meaningful coverage.
pytest -qHighlights:
- Tests avoid external systems (no real filesystem/network) and use in‑memory stubs.
- Each test follows Arrange–Act–Assert with clear failure messages.
- GUI tests run headless using stubbed Tk/ttk/dialogs and in‑memory paths.
For policy details, see the Unit Test Policy in the repository/docs (summarized in project memory and enforced in recent tests under
tests/).
- Protocols first. Interfaces in
data_model/interfacesdecouple parsing/emission from concrete types. - Wrappers.
q_wrapperclasses provide convenient, typed containers that satisfy the interfaces. - Adapter controller.
controllers/qif_loader.pybridges raw QIF text to protocol‑compliant transactions, centralizing date/amount parsing, splits handling, and cleared‑status mapping. - GUI separation.
gui_viewers/*uses the model and controller layers without embedding parsing logic in the UI.
The Convert tab uses profile definitions for Quicken Windows/Mac CSV flavors in quicken_helper/gui_viewers/csv_profiles.py. These define headers and writer helpers to ensure exported CSVs match what Quicken expects on each platform.
- Continue tightening the interface contracts and wrappers for additional Quicken constructs.
- Expand CSV profile coverage and add simple CLI entry points for batch operations.
- Stabilize Merge tab APIs for improved testability and extension points.
- GUI won’t start: Ensure Tkinter is available in your Python build. On some Linux distros, install
tkseparately. - Parsing differences across files: Use the Probe tab to inspect inputs and compare emitted outputs. File a test case reproducer if behavior diverges.
- Line endings (Windows vs Mac): CSV writers and tests account for platform differences; prefer opening files in text mode with explicit newline handling if scripting.
This project is part of a broader effort to modernize Quicken data handling with typed, testable components and a practical GUI for everyday tasks.