Skip to main content

CCV Generator

Helps import and generate CCVs (Canadian Common CV) by relying on an intermediary yaml format. The generated XML files can then be imported in the CCV website. In short, it helps you:

  • Convert an XML CCV to a readable and editable yaml format
  • Convert a yaml CCV to an XML CCV (so that it can be imported in the CCV website)
  • Generate a new CCV from scratch using a yaml template

The code can also be used as an API to build CCV generators.

Installation

pip install ccv_generator

Usage (Command line)

ccv_generator -h
usage: ccv_generator [-h] [-i INPUT] [-f FILTER] [-q | --quiet | --no-quiet] output

Generate a CCV XML file from a YAML file. Or export a CCV XML file to a YAML file.

positional arguments:
  output                The output file. Can be either a CCV XML file or a YAML file.

options:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        The input file. Can be either a CCV XML file or a YAML file.
  -f FILTER, --filter FILTER
                        Filter to parse only a subset of the CCV XML file. Should be a path of the section(s) to parse (e.g., "Contributions/Publications/Conference Publications" to export
                        only Conference Publications)
  -q, --quiet, --no-quiet
                        Avoid adding comments to the generated yaml file (default: False)

Examples

Convert a CCV XML file to a YAML file

ccv_generator -i ccv.xml ccv.yaml

Convert a YAML file to a CCV XML file

ccv_generator -i ccv.yaml ccv.xml

Generate a CCV yaml template

ccv_generator ccv.yaml

This will generate a CCV yaml file with the default structure. You can then edit the file and use it to generate a CCV XML file. You can also only generate a specific section of the CCV (e.g., only conference publications) by using the -f option:

ccv_generator -f "Contributions/Publications/Conference Publications" ccv.yaml

Usage (API)

Two functions are exposed to read and generate CCV xml files from/to python dictionaries:

parse_xml_ccv, build_xml_ccv

  • parse_xml_ccv(tree_model, section_filter=[], add_comments=True) -> dict: Reads an XML structure and returns a dictionary representation of the CCV.
  • build_xml_ccv(data) -> str: Builds an XML structure from a dictionary representation of the CCV. The dictionary should be in the format expected by the CCV XML schema.

Example

Converting a bibtex (.bib) to the publication section of the CCV that can be imported in the CCV website (requires pybtex):

from pybtex.database.input import bibtex
from ccv_generator import build_xml_ccv
import xml.etree.ElementTree as ET

MY_NAME = "John Doe"

publications = {
    "Contributions": {
        "Publications": {
            "Journal Articles": [],
        }
    }
}
parser = bibtex.Parser()
bib_data = parser.parse_file('publications.bib')


def get_author(author):
    return " ".join(author.first_names) + " " + " ".join(author.last_names)

def location_to_country(location):
    location = location.split(",")[-1].strip()
    if location == "USA": location = "United States of America"
    return location


for entry in bib_data.entries:
    entry_data = bib_data.entries[entry]
    publication = {}

    author_position = 1

    if get_author(entry_data.persons["author"][0]) == MY_NAME:
        author_position = 0
    elif get_author(entry_data.persons["author"][-1]) == MY_NAME:
        author_position = -1


    publication["Contribution Role"] = "Co-Author"
    if author_position == 0:
        publication["Contribution Role"] = "First Listed Author"
    elif author_position == -1:
        publication["Contribution Role"] = "Last Listed Author"

    publication["Contribution Percentage"] = "81-90" if author_position == 0 else "31-40"
    publication["Number of Contributors"] = str(len(entry_data.persons["author"]))

    publication["Authors"] = "; ".join([str(author) for author in entry_data.persons["author"]])

    if "journal" in entry_data.fields:
        publication["Article Title"] = entry_data.fields["title"]
        publication["Journal"] = entry_data.fields["journal"]
        publication["Volume"] = entry_data.fields["volume"]
        #publication["Issue"] = 
        publication["Page Range"] = entry_data.fields["pages"] if "pages" in entry_data.fields else "1-" + entry_data.fields["numpages"]
        publication["Publishing Status"] = "Published"
        publication["Year"] = entry_data.fields["year"]
        #publication["Publisher"] = entry_data.fields["publisher"]
        #publication["Description / Contribution Value"] = 
        publication["URL"] = entry_data.fields["url"]
        publication["Refereed?"] = "Yes"
        #publication["Open Access"] = "Yes"
        #publication["Synthesis?"] = "Yes"
        publication["DOI"] = entry_data.fields["doi"]

        publications["Contributions"]["Publications"]["Journal Articles"].append(publication)

output_root = build_xml_ccv(publications)

# write to file (idented)
ET.indent(output_root)
output_tree = ET.ElementTree(output_root)
output_tree.write("publications.xml", encoding="utf-8", xml_declaration=True, method="xml")

Note: some fields are required from the CCV but missing from the bibtex (e.g., contribution percentage, contribution value). In the example, some of thee fields are being reconstructed from the info we do have. The others are left blank.

Metadata

Release files for ccv-generator 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ccv-generator 0.1.1
File Size Uploaded
ccv_generator-0.1.1.tar.gz 10.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ccv-generator 0.1.1
File Interpreter ABI Platform
ccv_generator-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 20.5 kB

Release files / ccv_generator-0.1.1.tar.gz

Download URL ccv_generator-0.1.1.tar.gz
Size 10.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f2d5ff7049c46bbb0ed6492db62d1b23dd4b2ae14cff79eac940e0325a7dfcf5
BLAKE2b-256 checksum
How to use checksums
5e11bbcd438721f9983ab6cf4e14a969e13dec9e97336d56fd2f605b710f3886
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 24, 2025.

Transparency log

Release files / ccv_generator-0.1.1-py3-none-any.whl

Download URL ccv_generator-0.1.1-py3-none-any.whl
Size 10.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
df778afba7dcf5176946bb675a99ec6f28b2f5226f8bcc3c18100ca222810d39
BLAKE2b-256 checksum
How to use checksums
6ec143714f407e8cc841fc8db605b59e5969c8f366fbae7ca4b1197cdd45f178
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 24, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page