Skip to content

safety ¤

Callable for Safety.

Functions:

  • check

    Run the safety check command.

check ¤

check(
    requirements: str | Sequence[str],
    *,
    ignore_vulns: dict[str, str] | None = None,
    formatter: Literal["json", "bare", "text"] = "text",
    full_report: bool = True
) -> bool

Run the safety check command.

This function makes sure we load the original, unpatched version of safety.

Parameters:

  • requirements (str | Sequence[str]) –

    Python "requirements" (list of pinned dependencies).

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

    Vulnerabilities to ignore.

  • formatter (Literal['json', 'bare', 'text'], default: 'text' ) –

    Report format.

  • full_report (bool, default: True ) –

    Whether to output a full report.

Returns:

  • bool

    Success/failure.

Source code in src/duty/callables/safety.py
13
14
15
16
17
18
19
20
21
22
23
24
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
@lazy(name="safety.check")
def check(
    requirements: str | Sequence[str],
    *,
    ignore_vulns: dict[str, str] | None = None,
    formatter: Literal["json", "bare", "text"] = "text",
    full_report: bool = True,
) -> bool:
    """Run the safety check command.

    This function makes sure we load the original, unpatched version of safety.

    Parameters:
        requirements: Python "requirements" (list of pinned dependencies).
        ignore_vulns: Vulnerabilities to ignore.
        formatter: Report format.
        full_report: Whether to output a full report.

    Returns:
        Success/failure.
    """
    # set default parameter values
    ignore_vulns = ignore_vulns or {}

    # undo possible patching
    # see https://github.com/pyupio/safety/issues/348
    for module in sys.modules:
        if module.startswith("safety.") or module == "safety":
            del sys.modules[module]

    importlib.invalidate_caches()

    # reload original, unpatched safety
    from safety.formatter import SafetyFormatter
    from safety.safety import calculate_remediations, check
    from safety.util import read_requirements

    # check using safety as a library
    if isinstance(requirements, (list, tuple, set)):
        requirements = "\n".join(requirements)
    packages = list(read_requirements(StringIO(cast(str, requirements))))

    # TODO: Safety 3 support, merge once support for v2 is dropped.
    check_kwargs = {"packages": packages, "ignore_vulns": ignore_vulns}
    try:
        from safety.auth.cli_utils import build_client_session

        client_session, _ = build_client_session()
        check_kwargs["session"] = client_session
    except ImportError:
        pass

    vulns, db_full = check(**check_kwargs)
    remediations = calculate_remediations(vulns, db_full)
    output_report = SafetyFormatter(formatter).render_vulnerabilities(
        announcements=[],
        vulnerabilities=vulns,
        remediations=remediations,
        full=full_report,
        packages=packages,
    )

    # print report, return status
    if vulns:
        print(output_report)  # noqa: T201
        return False
    return True