Search code examples
pythonyamlruamel.yaml

Lose quotes around date when writing to YAML file


I have this script:

import json
from datetime import datetime, timedelta
import os
import ruamel.yaml

vulnerabilities = {}
expiration_date = (datetime.now() + timedelta(days=29)).strftime('%Y-%m-%d')
vulnerabilities = [{'expirationDate': expiration_date}]

output_file = 'output_whitelist.yaml'

yaml = ruamel.yaml.YAML()
yaml.default_flow_style = False
with open(output_file, 'w') as file:
    yaml.dump({f'vulnerabilities': vulnerabilities}, file)

The output shows this:

vulnerabilities:
  - expirationDate: '2024-08-16'

but I would like to show it like this:

vulnerabilities:
  - expirationDate: 2024-08-16

without the quotes. Is this possible?

I tried using a custom representer, but that didn't work:

# Custom representer for datetime.date objects
def date_representer(dumper, data):
    return dumper.scalar(u'tag:yaml.org,2002:str', data)

yaml.add_representer(datetime.date, date_representer)

Solution

  • Your initial approach didn't work because the custom representer was designed for datetime.date objects but was applied to strings, leading to dates being treated and quoted as plain strings in the YAML.

    This should work:

    from datetime import datetime, timedelta
    import os
    import ruamel.yaml
    
    def str_representer(dumper, data):
        try:
            datetime.strptime(data, '%Y-%m-%d')
            return dumper.represent_scalar('tag:yaml.org,2002:timestamp', data)
        except ValueError:
            return dumper.represent_scalar('tag:yaml.org,2002:str', data)
    
    yaml = ruamel.yaml.YAML()
    yaml.default_flow_style = False
    yaml.representer.add_representer(str, str_representer)
    
    vulnerabilities = {}
    expiration_date = (datetime.now() + timedelta(days=29)).strftime('%Y-%m-%d')
    vulnerabilities = [{'expirationDate': expiration_date}]
    
    script_dir = os.path.dirname(os.path.abspath(__file__))
    
    output_file = os.path.join(script_dir, 'output_whitelist.yaml')
    
    with open(output_file, 'w') as file:
        yaml.dump({'vulnerabilities': vulnerabilities}, file)