Coverage for rendercv/data/reader.py: 100%
27 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-12-25 23:06 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-12-25 23:06 +0000
1"""
2The `rendercv.data.reader` module contains the functions that are used to read the input
3file (YAML or JSON) and return them as an instance of `RenderCVDataModel`, which is a
4Pydantic data model of RenderCV's data format.
5"""
7import pathlib
8from typing import Optional
10import ruamel.yaml
12from . import models
15def read_a_yaml_file(file_path_or_contents: pathlib.Path | str) -> dict:
16 """Read a YAML file and return its content as a dictionary. The YAML file can be
17 given as a path to the file or as the contents of the file as a string.
19 Args:
20 file_path_or_contents: The path to the YAML file or the contents of the YAML
21 file as a string.
23 Returns:
24 The content of the YAML file as a dictionary.
25 """
26 if isinstance(file_path_or_contents, pathlib.Path):
27 # Check if the file exists:
28 if not file_path_or_contents.exists():
29 message = f"The input file {file_path_or_contents} doesn't exist!"
30 raise FileNotFoundError(message)
32 # Check the file extension:
33 accepted_extensions = [".yaml", ".yml", ".json", ".json5"]
34 if file_path_or_contents.suffix not in accepted_extensions:
35 user_friendly_accepted_extensions = [
36 f"[green]{ext}[/green]" for ext in accepted_extensions
37 ]
38 user_friendly_accepted_extensions = ", ".join(
39 user_friendly_accepted_extensions
40 )
41 message = (
42 "The input file should have one of the following extensions:"
43 f" {user_friendly_accepted_extensions}. The input file is"
44 f" {file_path_or_contents}."
45 )
46 raise ValueError(message)
48 file_content = file_path_or_contents.read_text(encoding="utf-8")
49 else:
50 file_content = file_path_or_contents
52 yaml_as_a_dictionary: dict = ruamel.yaml.YAML().load(file_content)
54 if yaml_as_a_dictionary is None:
55 message = "The input file is empty!"
56 raise ValueError(message)
58 return yaml_as_a_dictionary
61def validate_input_dictionary_and_return_the_data_model(
62 input_dictionary: dict,
63 context: Optional[dict] = None,
64) -> models.RenderCVDataModel:
65 """Validate the input dictionary by creating an instance of `RenderCVDataModel`,
66 which is a Pydantic data model of RenderCV's data format.
68 Args:
69 input_dictionary: The input dictionary.
70 context: The context dictionary that is used to validate the input dictionary.
71 It's used to send the input file path with the context object, but it's not
72 required.
74 Returns:
75 The data model.
76 """
77 # Validate the parsed dictionary by creating an instance of RenderCVDataModel:
78 return models.RenderCVDataModel.model_validate(input_dictionary, context=context)
81def read_input_file(
82 file_path_or_contents: pathlib.Path | str,
83) -> models.RenderCVDataModel:
84 """Read the input file (YAML or JSON) and return them as an instance of
85 `RenderCVDataModel`, which is a Pydantic data model of RenderCV's data format.
87 Args:
88 file_path_or_contents: The path to the input file or the contents of the input
89 file as a string.
91 Returns:
92 The data model.
93 """
94 input_as_dictionary = read_a_yaml_file(file_path_or_contents)
96 return validate_input_dictionary_and_return_the_data_model(input_as_dictionary)