Skip to content

rendercv_model_builder

BuildRendercvModelArguments

Bases: TypedDict

design_yaml_file instance-attribute

dont_generate_html instance-attribute

dont_generate_markdown instance-attribute

dont_generate_pdf instance-attribute

dont_generate_png instance-attribute

dont_generate_typst instance-attribute

html_path instance-attribute

locale_yaml_file instance-attribute

markdown_path instance-attribute

output_folder instance-attribute

overrides instance-attribute

pdf_path instance-attribute

png_path instance-attribute

settings_yaml_file instance-attribute

typst_path instance-attribute

build_rendercv_dictionary(main_yaml_file, **kwargs)

Merge main YAML with overlays and CLI overrides into final dictionary.

Parameters:

  • main_yaml_file (str) –

    Primary CV YAML content string.

  • kwargs (Unpack[BuildRendercvModelArguments], default: {} ) –

    Optional YAML overlay strings, output paths, generation flags, and CLI overrides.

Returns:

  • tuple[CommentedMap, dict[str, CommentedMap]]

    Tuple of merged dictionary and overlay source CommentedMaps (for error reporting).

Source code in src/rendercv/schema/rendercv_model_builder.py
def build_rendercv_dictionary(
    main_yaml_file: str,
    **kwargs: Unpack[BuildRendercvModelArguments],
) -> tuple[CommentedMap, dict[str, CommentedMap]]:
    """Merge main YAML with overlays and CLI overrides into final dictionary.

    Args:
        main_yaml_file: Primary CV YAML content string.
        kwargs: Optional YAML overlay strings, output paths, generation flags, and CLI overrides.

    Returns:
        Tuple of merged dictionary and overlay source CommentedMaps (for error reporting).
    """
    input_dict = read_yaml_with_validation_errors(main_yaml_file, "main_yaml_file")
    input_dict.setdefault("settings", {}).setdefault("render_command", {})

    yaml_overlays: dict[OverlaySourceKey, str | None] = {
        "settings": kwargs.get("settings_yaml_file"),
        "design": kwargs.get("design_yaml_file"),
        "locale": kwargs.get("locale_yaml_file"),
    }

    overlay_sources: dict[str, CommentedMap] = {}
    for key, yaml_content in yaml_overlays.items():
        if yaml_content:
            overlay_cm = read_yaml_with_validation_errors(
                yaml_content, OVERLAY_SOURCE_TO_YAML_SOURCE[key]
            )
            input_dict[key] = overlay_cm[key]
            overlay_sources[key] = overlay_cm

    render_overrides: dict[str, pathlib.Path | str | bool | None] = {
        "output_folder": kwargs.get("output_folder"),
        "typst_path": kwargs.get("typst_path"),
        "pdf_path": kwargs.get("pdf_path"),
        "markdown_path": kwargs.get("markdown_path"),
        "html_path": kwargs.get("html_path"),
        "png_path": kwargs.get("png_path"),
        "dont_generate_typst": kwargs.get("dont_generate_typst"),
        "dont_generate_html": kwargs.get("dont_generate_html"),
        "dont_generate_markdown": kwargs.get("dont_generate_markdown"),
        "dont_generate_pdf": kwargs.get("dont_generate_pdf"),
        "dont_generate_png": kwargs.get("dont_generate_png"),
    }

    for key, value in render_overrides.items():
        if value:
            input_dict["settings"]["render_command"][key] = value

    overrides = kwargs.get("overrides")
    if overrides:
        input_dict = apply_overrides_to_dictionary(input_dict, overrides)

    return input_dict, overlay_sources

build_rendercv_dictionary_and_model(main_yaml_file, *, input_file_path=None, **kwargs)

Complete pipeline from raw YAML string to validated model.

Parameters:

  • main_yaml_file (str) –

    Primary CV YAML content string.

  • input_file_path (Path | None, default: None ) –

    Source file path for validation context (path resolution).

  • kwargs (Unpack[BuildRendercvModelArguments], default: {} ) –

    Optional YAML overlay strings, output paths, generation flags, and CLI overrides.

Returns:

  • tuple[CommentedMap, RenderCVModel]

    Tuple of merged dictionary and validated model.

Source code in src/rendercv/schema/rendercv_model_builder.py
def build_rendercv_dictionary_and_model(
    main_yaml_file: str,
    *,
    input_file_path: pathlib.Path | None = None,
    **kwargs: Unpack[BuildRendercvModelArguments],
) -> tuple[CommentedMap, RenderCVModel]:
    """Complete pipeline from raw YAML string to validated model.

    Args:
        main_yaml_file: Primary CV YAML content string.
        input_file_path: Source file path for validation context (path resolution).
        kwargs: Optional YAML overlay strings, output paths, generation flags, and CLI overrides.

    Returns:
        Tuple of merged dictionary and validated model.
    """
    d, overlay_sources = build_rendercv_dictionary(main_yaml_file, **kwargs)
    m = build_rendercv_model_from_commented_map(d, input_file_path, overlay_sources)
    return d, m

build_rendercv_model_from_commented_map(commented_map, input_file_path=None, overlay_sources=None)

Validate merged dictionary and build Pydantic model with error mapping.

Parameters:

  • commented_map (CommentedMap | dict[str, Any]) –

    Merged dictionary with line/column metadata.

  • input_file_path (Path | None, default: None ) –

    Source file path for context and photo resolution.

  • overlay_sources (dict[str, CommentedMap] | None, default: None ) –

    Per-section CommentedMaps from overlays (for correct error coordinates).

Returns:

Source code in src/rendercv/schema/rendercv_model_builder.py
def build_rendercv_model_from_commented_map(
    commented_map: CommentedMap | dict[str, Any],
    input_file_path: pathlib.Path | None = None,
    overlay_sources: dict[str, CommentedMap] | None = None,
) -> RenderCVModel:
    """Validate merged dictionary and build Pydantic model with error mapping.

    Args:
        commented_map: Merged dictionary with line/column metadata.
        input_file_path: Source file path for context and photo resolution.
        overlay_sources: Per-section CommentedMaps from overlays (for correct error coordinates).

    Returns:
        Validated RenderCVModel instance.
    """
    try:
        validation_context = {
            "context": ValidationContext(
                input_file_path=input_file_path,
                current_date=commented_map.get("settings", {}).get("current_date"),
            )
        }
        model = RenderCVModel.model_validate(commented_map, context=validation_context)
    except pydantic.ValidationError as e:
        validation_errors = parse_validation_errors(e, commented_map, overlay_sources)
        raise RenderCVUserValidationError(validation_errors) from e

    return model

get_yaml_error_location(error)

Extract 1-indexed line/column coordinates from ruamel parser errors.

Parameters:

  • error (YAMLError) –

    YAML parsing exception raised by ruamel.

Returns:

  • YamlLocation | None

    Start/end coordinates when available, otherwise None.

Source code in src/rendercv/schema/rendercv_model_builder.py
def get_yaml_error_location(error: ruamel.yaml.YAMLError) -> YamlLocation | None:
    """Extract 1-indexed line/column coordinates from ruamel parser errors.

    Args:
        error: YAML parsing exception raised by ruamel.

    Returns:
        Start/end coordinates when available, otherwise None.
    """
    context_mark = getattr(error, "context_mark", None)
    problem_mark = getattr(error, "problem_mark", None)
    start_mark = context_mark or problem_mark
    end_mark = problem_mark or context_mark

    if start_mark is None or end_mark is None:
        return None

    return (
        (start_mark.line + 1, start_mark.column + 1),
        (end_mark.line + 1, end_mark.column + 1),
    )

read_yaml_with_validation_errors(yaml_content, yaml_source)

Parse YAML content and convert parser failures into validation errors.

Why

YAML syntax errors should use the same error pipeline as schema validation, so the CLI can display all input issues through one consistent path.

Parameters:

  • yaml_content (str) –

    YAML string content.

  • yaml_source (YamlSource) –

    Which input file this YAML content came from.

Returns:

  • CommentedMap

    Parsed YAML map preserving source coordinates.

Raises:

Source code in src/rendercv/schema/rendercv_model_builder.py
def read_yaml_with_validation_errors(
    yaml_content: str, yaml_source: YamlSource
) -> CommentedMap:
    """Parse YAML content and convert parser failures into validation errors.

    Why:
        YAML syntax errors should use the same error pipeline as schema validation,
        so the CLI can display all input issues through one consistent path.

    Args:
        yaml_content: YAML string content.
        yaml_source: Which input file this YAML content came from.

    Returns:
        Parsed YAML map preserving source coordinates.

    Raises:
        RenderCVUserValidationError: If YAML cannot be parsed.
    """
    try:
        return read_yaml(yaml_content)
    except ruamel.yaml.YAMLError as e:
        parser_message = str(e).splitlines()[0].strip()
        if not parser_message.endswith("."):
            parser_message += "."

        raise RenderCVUserValidationError(
            validation_errors=[
                RenderCVValidationError(
                    schema_location=None,
                    yaml_location=get_yaml_error_location(e),
                    yaml_source=yaml_source,
                    message=f"This is not a valid YAML file. {parser_message}",
                    input="...",
                )
            ]
        ) from e