If you have ever written a one off script to read a CSV that was not really a CSV, this one is for you. It is a small open source Python package built around a pattern more of us should borrow: the model writes code once, and deterministic code does every run after that.
Lab instruments are a great stress test for parsers. A plate reader writes a metadata header, then a grid of wells per reading cycle, then maybe a temperature column, all in a layout that changes between vendors and sometimes between firmware versions. Most labs end up with a folder of throwaway scripts, one per instrument, each quietly breaking the next time someone changes an export setting.
Recipes Instead of Scripts
labparse splits the job in two. A format is described by a recipe, a small JSON file that says where the header ends, how the grid is laid out, and how time and cycle numbers are read. A deterministic engine executes the recipe. It ships with recipes for Tecan ASCII exports, SoftMax Pro and SpectraMax kinetic files, generic wide and long CSV or TSV tables, and Excel workbooks with a plate grid.
Every parse produces the same tidy schema whatever the instrument: well, row, col, cycle, time_s and value, plus any extra columns like temperature.
import labparse
result = labparse.parse("growth.asc")
result.data # tidy pandas DataFrame
result.wide() # one column per well
result.save_csv("tidy.csv")
Where the LLM Comes In, and Where It Does Not
When labparse meets a format it has no recipe for, it shows the raw file to your own model once and asks it to write a new recipe. That is the only job the model gets. The recipe is then run by the same engine against your actual file, and it is only accepted if the parse succeeds. A wrong recipe is rejected and retried, so a bad guess can never turn into silently wrong numbers.
Accepted recipes are cached in your home directory, so each new format costs at most one model call ever, and cached formats parse offline. Recipes are plain JSON, which means you can read them, fix them by hand, and share them with the rest of your lab.
For the model it checks, in order: the Claude CLI, the Codex CLI, an Anthropic API key, then an OpenAI API key, and a base URL setting points it at any OpenAI compatible server, local models included. With no model configured, everything with a bundled or cached recipe still works, and an unknown format gets a clear message instead of a guess.
Why This Pattern Travels
The part worth taking to other projects is the split. The model proposes, the deterministic engine disposes, and your data only ever flows through code you can inspect. It fits log formats, bank statement exports, legacy reports, anything where the variety of inputs is the real problem and the correctness of the output is not negotiable.
The Takeaway
Let the LLM write the parser, verify it against real input, cache the result, and never let it touch the numbers directly. labparse is MIT licensed, installs with pip install labparse, and the project page above links to the source and issue tracker.