import argparse import json from pathlib import Path from jinja2 import Environment, FileSystemLoader from schema import DocumentInput def parse_args() -> argparse.Namespace: # keep cli parsing separate so main stays about workflow parser = argparse.ArgumentParser(description="Render document from JSON + Jinja2 template") parser.add_argument( "--input", "-i", type=Path, required=True, help="Path to input JSON file (e.g. examples/input.json)" ) parser.add_argument( "--template", "-t", default="doc.md.j2", help="Template file (e.g. doc.md.j2)" ) parser.add_argument( "--output", "-o", type=Path, required=True, help="Path to write rendered output (e.g. out.md)" ) return parser.parse_args() def render_template(template_name: str, data: dict) -> str: # Jinja env points at templates/ env = Environment(loader=FileSystemLoader("templates"), trim_blocks=True, lstrip_blocks=True) template = env.get_template(template_name) return template.render(data) def main(): args = parse_args() # load input data # path() over hardcoding str data = json.loads(args.input.read_text(encoding="utf-8")) # validate + normalise input doc_input = DocumentInput(**data) # load template to render out = render_template(args.template, doc_input.model_dump()) # write output - render md to file args.output.write_text(out, encoding="utf-8") print(f"wrote {args.output}") if __name__ == "__main__": main()