Skip to content

validation.py

The validate function calls checkers to validate files and combines the results in the requested format.

validate(filename, checkers=[check_ags], standard_AGS4_dictionary=None)

Validate filename (against optional dictionary) and respond in dictionary suitable for converting to JSON.

:raises ValueError: Raised if dictionary provided is not available.

Source code in app/validation.py
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
def validate(
    filename: Path,
    checkers: List[Callable[[Path], dict]] = [check_ags],
    standard_AGS4_dictionary: Optional[str] = None,
) -> dict:
    """
    Validate filename (against optional dictionary) and respond in
    dictionary suitable for converting to JSON.

    :raises ValueError: Raised if dictionary provided is not available.
    """
    logger.info("Validate called for %s", filename.name)

    # Prepare response with metadata
    response = _prepare_response_metadata(filename)

    # Select dictionary file if exists
    if standard_AGS4_dictionary:
        try:
            dictionary_file = STANDARD_DICTIONARIES[standard_AGS4_dictionary]
        except KeyError:
            msg = (
                f"{standard_AGS4_dictionary} not available.  "
                f"Installed dictionaries: {STANDARD_DICTIONARIES.keys()}"
            )
            raise ValueError(msg)
    else:
        dictionary_file = None

    all_errors = {}
    all_checkers = []
    error_count = warnings_count = fyi_count = 0
    additional_metadata_responses = {"bgs": {}, "ags": {}}
    # Don't process if file is not .ags format
    if filename.suffix.lower() != ".ags":
        error_count = 1
        all_errors.update(
            {
                "File read error": [
                    {
                        "line": "-",
                        "group": "",
                        "desc": f"{filename.name} is not an .ags file",
                    }
                ]
            }
        )
    else:
        # Run checkers to extract errors and other metadata
        for checker in checkers:
            # result is a dictionary with 'errors', 'checker' and other keys
            result: dict = checker(filename, standard_AGS4_dictionary=dictionary_file)

            # Extract 'common' data
            all_errors.update(result.pop("errors"))
            current_checker = result.pop("checker")
            all_checkers.append(current_checker)

            additional_metadata = result.pop("additional_metadata")
            if current_checker.startswith("bgs_rules"):
                additional_metadata_responses["bgs"] = additional_metadata
            else:
                additional_metadata_responses["ags"] = additional_metadata

            error_count += result["error_count"]
            warnings_count += result["warnings_count"]
            fyi_count += result["fyi_count"]

            # Add remaining keys to response
            response.update(result)

    # Use BGS metadata where available, as it contains more data
    if additional_metadata_responses["bgs"]:
        response["additional_metadata"] = additional_metadata_responses["bgs"]
    else:
        response["additional_metadata"] = additional_metadata_responses["ags"]

    if error_count > 0:
        message = f"{error_count} error(s) found in file!"
        valid = False
    else:
        message = "No errors found!"
        valid = True

    if warnings_count > 0:
        message += f" {warnings_count} warnings(s) found in file."
    if fyi_count > 0:
        message += f" {fyi_count} FYI(s) found in file."

    response.update(
        errors=all_errors,
        message=message,
        valid=valid,
        checkers=all_checkers,
        error_count=error_count,
        warnings_count=warnings_count,
        fyi_count=fyi_count,
    )

    return response

to_plain_text(response)

Take JSON response from convert and render as plain text.

Source code in app/validation.py
127
128
129
def to_plain_text(response: dict) -> str:
    """Take JSON response from convert and render as plain text."""
    return PLAIN_TEXT_TEMPLATE.render(response)