diff --git a/oslo_utils/fileutils.py b/oslo_utils/fileutils.py index 909ed4b9..36c0049a 100644 --- a/oslo_utils/fileutils.py +++ b/oslo_utils/fileutils.py @@ -22,10 +22,12 @@ File utilities. import contextlib import errno import hashlib +import json import os import stat import tempfile import time +import yaml from oslo_utils import excutils @@ -158,3 +160,50 @@ def last_bytes(path, num): raise unread_bytes = fp.tell() return (fp.read(), unread_bytes) + + +def is_json(file_path): + """Check if file is of json type or not. + + This function try to load the input file using json.loads() + and return False if ValueError otherwise True. + + :param file_path: The file path to check + + :returns: bool + + """ + with open(file_path, 'r') as fh: + data = fh.read() + try: + json.loads(data) + return True + except ValueError: + return False + + +def is_yaml(file_path): + """Check if file is of yaml type or not. + + This function try to load the input file using yaml.safe_load() + and return True if loadable. Because every json file can be loadable + in yaml, so this function return False if file is loadable using + json.loads() means it is json file. + + :param file_path: The file path to check + + :returns: bool + + """ + with open(file_path, 'r') as fh: + data = fh.read() + is_yaml = False + try: + json.loads(data) + except ValueError: + try: + yaml.safe_load(data) + is_yaml = True + except yaml.scanner.ScannerError: + pass + return is_yaml diff --git a/oslo_utils/tests/test_fileutils.py b/oslo_utils/tests/test_fileutils.py index 7e089c81..f70b2f4f 100644 --- a/oslo_utils/tests/test_fileutils.py +++ b/oslo_utils/tests/test_fileutils.py @@ -15,6 +15,7 @@ import errno import hashlib +import json import os import shutil import stat @@ -22,13 +23,13 @@ import tempfile import time from unittest import mock import uuid +import yaml from oslotest import base as test_base import six from oslo_utils import fileutils - TEST_PERMISSIONS = stat.S_IRWXU @@ -289,3 +290,30 @@ class LastBytesTestCase(test_base.BaseTestCase): def test_non_exist_file(self): self.assertRaises(IOError, fileutils.last_bytes, 'non_exist_file', 1000) + + +class FileTypeTestCase(test_base.BaseTestCase): + """Test the is_yaml() and is_json() utility methods.""" + + def setUp(self): + super(FileTypeTestCase, self).setUp() + data = { + 'name': 'test', + 'website': 'example.com' + } + temp_dir = tempfile.mkdtemp() + self.json_file = tempfile.mktemp(dir=temp_dir) + self.yaml_file = tempfile.mktemp(dir=temp_dir) + + with open(self.json_file, 'w') as fh: + json.dump(data, fh) + with open(self.yaml_file, 'w') as fh: + yaml.dump(data, fh) + + def test_is_json(self): + self.assertTrue(fileutils.is_json(self.json_file)) + self.assertFalse(fileutils.is_json(self.yaml_file)) + + def test_is_yaml(self): + self.assertTrue(fileutils.is_yaml(self.yaml_file)) + self.assertFalse(fileutils.is_yaml(self.json_file)) diff --git a/releasenotes/notes/add-methods-for-json-yaml-file-check-746dca0a11c2f9c9.yaml b/releasenotes/notes/add-methods-for-json-yaml-file-check-746dca0a11c2f9c9.yaml new file mode 100644 index 00000000..87817647 --- /dev/null +++ b/releasenotes/notes/add-methods-for-json-yaml-file-check-746dca0a11c2f9c9.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + New method ``is_json`` ``is_yaml`` added in fileutils. + These can be used to check if file is JSON or YAML + formatted.