Making an HTML CV in Python using Jinja

Posted on Fri 07 June 2019 in python


This blog post will walk you through the basics of generating your CV using Python and Jinja. In addition, I have a GitHub repo with a full example. To see a finished product, go here.

I have previously created my Curriculum Vitae (CV) in both Word and LaTeX, and found that neither had the flexibility that I wanted. Ideally, I want to future-proof my CV so that it's easy to do things like change formatting without having to manually edit every entry into the CV. To do that, it seems intuitive that you would want a standardized data format to carry your CV data and a template to format that code into your CV design. The data format should look something like json or YAML:

            "place": "University of California, San Diego, CA",
            "start": "2015",
            "end": "now",
            "degree": "Ph.D. in Psychology with a Specialization in Anthropogeny",
            "lab": "Auditory Neuroscience Laboratory",
            "advisor": "Timothy Q. Gentner"
            "place": "The Pennsylvania State University, State College, PA",
            "start": "2010",
            "end": "2014",
            "degree": "B.A. in Psychology with a Minor in Biology"

The ideal CV should be fairly future proof:

  1. It shouldn't rely on software that isn't very well supported.
  2. The data format should be standardized.
  3. It should be really easy to make changes.

When I searched around I found a few examples that I really liked. The three implementations I liked best were:

  1. JSON resume, takes your resume as a JSON file, and can generate your resume in many different formats. This is probably the most full featured resume builder I found.
  2. Brandon Amos's Resume (example) takes in YAML files and generates MD, LaTeX, PDF, and HTML files from the YAML.
  3. Colin Rafel's CV (example) takes your CV as a JSON file and generates an HTML file from the JSON in Python using Jinja.

The three methods are all pretty similar. I ended up using the Colin Rafel method as the basis for my CV because I wanted to rely only on code that is either (1) self-contained within the repository or (2) very well supported external software. All this code relies upon is (1) Python and (2) Jinja2.

A quick introduction

The resume in formatted around a template file (here .tpl) that is basically just HTML:

In [ ]:
<html xmlns="" xml:lang="en" lang="en">
        <title>Tim Sainburg: Curriculum Vitae</title>
        <div class="block">
            {% for item in education %}
            <div class="item">
                <div class="yearrange">{{item.start}}&#8211;{{item.end}}</div>
                <div class="yearright">
                    <strong>{{}}</strong><br />
                    {{}}<br />
                    {% if item.lab %}{{item.lab}}<br />{% endif %}
                    {% if item.advisor %}Advisor: {{item.advisor}}<br />{% endif %}
            {% endfor %}

Resume data is stored in a JSON, like this:

In [ ]:
            "Organization": "University of California, San Diego",
            "lab": "Auditory Neurscience Laboratory",
            "location": "La Jolla, CA",
            "advisor": "Timothy Q Gentner",
            "start": "2015",
            "end": "now",
            "title": "PhD Student"

Python and Jinja read the resume data in the json, and generate an HTML file from the template:

In [ ]:
data = json.load('MYJSONFILE.JSON')

env = jinja2.environment.Environment(
template = env.get_template('MYTEMPLATE.TPL')
with open('/MY/OUTPUT/PATH/MYTEMPLATE.HTML', "w") as f:

That's basically it. There is a bunch you can do from there, but so long as you know some basic Python, HTML, and CSS, you can make a great resume or CV. For a full CV example check out either my repo on GitHub, or the one I based mine off of.