The problem
A program often needs structured data from text: the fields of an invoice, the date in an email. A language model can be asked to read the text and answer in JSON (JavaScript Object Notation, a text format for structured data). But its output is not always clean: it may wrap the JSON in a markdown fence, or add a sentence before it ("Sure! Here it is:"), or return a field of the wrong type. So the pipeline has two parts: a tolerant parser that finds the JSON, and a strict validator that checks it against a schema.
Part 1: finding the JSON object
parse_json_object(text) returns the first JSON object in text as a dict, or None if there is none. Scan for each {, and try json.JSONDecoder().raw_decode(text, i) from there (it decodes one JSON value starting at position i and ignores what comes after); return the first result that decodes to a dict.
Example. The text is
Sure! Here it is:, a newline, a markdown fence, and{"vendor": "ACME", "total": 42, "paid": true}. The first{starts a valid object: the result is{"vendor": "ACME", "total": 42, "paid": True}. A text with no valid object, such asno json, givesNone.
Part 2: validation
The schema maps field names to (type, required), where the type is one of str, int, float, bool, list. validate(obj, schema) returns a list of error strings, empty if valid:
"missing: <field>"for a required field that is absent;"type: <field>"for a present field of the wrong type. Afloatfield also accepts anint, but no field accepts aboolunless its type isbool(in PythonTrueis anint);"extra: <field>"for any field not in the schema.
Report errors in schema order, then extras in the object's order.
Example.
schema = {"vendor": (str, True), "total": (float, True), "date": (str, False)}.
{"vendor": "ACME", "total": 42, "paid": true}:["extra: paid"]. The42is accepted as a float; the optionaldateis absent, which is fine.{"total": "42"}:["missing: vendor", "type: total"]: the total is text, not a number.
Part 3: both together
extract(text, schema) returns (obj, errors). If no object can be parsed: (None, ["no json object"]).
What to implement
parse_json_object(text),validate(obj, schema)andextract(text, schema)as described.
Requirements
- Standard library only (
json).