Contract Clause Extractor
creation : Contract Clause Extractor
An entry from the chronicle of built things — its purpose, its materials, and the bargains struck along the way.
Built in an evening off the back of a hiring exercise, as a hands-on run at the FastAPI and Pydantic stack with a model behind it. Paste or upload a contract and the service returns structured metadata and risk flags as validated JSON, with a React front end whose types mirror the Pydantic models on the other side of the wire.
Pydantic is the contract with the model, not only the guard after it. The JSON schema carried in the prompt is generated from the same models that validate the response, so there is one definition point instead of a prompt and a validator free to drift apart. The prompt forbids inferring anything the contract does not state — nulls over guesses.
When validation fails, the validation error is handed back to the model for exactly one retry, and the response reports that it retried, so callers can watch how often it happens rather than discovering it later. A stub mode returns a canned response, which makes the whole plumbing testable with no API key and no spend.
tech_stackInventory of Materials
- FastAPIAPI
- PydanticValidation
- ClaudeExtraction
- ReactInterface
- TypeScriptLanguage
- ViteBuild



Engineering Tradeoffs
One retry, not a loop. Feeding the validation error back recovers the common malformed-response case, and capping it at one keeps a pathological document from burning tokens indefinitely — while the reported flag turns the failure rate into something observable instead of something hidden.
Deliberately unfinished, and it says so in its own README. Plain text in only, no PDF parsing, no eval suite, no auth or rate limiting, and one document per request with no chunking past the context window. Each of those is real work; naming them is more useful than a README that implies they are already there.
It was never deployed, and that is the honest end of it. An extraction endpoint holding an API key needs authentication, rate limiting and a spend ceiling before it can face the internet, and none of those were what the exercise was about — so the record is the code and the reasoning, not a live URL.