Skip to content

Commit 3ad49dd

Browse files
committed
added new example notebooks
1 parent 04f4ae8 commit 3ad49dd

9 files changed

Lines changed: 2022 additions & 24 deletions

File tree

docs/_toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ parts:
8080
- file: apidocs/api_intro
8181
sections:
8282
- file: examples/ca_api_example_overview
83+
- file: examples/example_risk_heatmap
84+
- file: examples/example_weakness_perfile_view
8385
- file: examples/ca_api_example_checks
8486
- file: examples/ca_api_example_scanning
8587
- file: examples/ca_api_example_json

docs/apidocs/codeaudit.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,9 @@ Public Interfaces module
1010
:undoc-members:
1111
:show-inheritance:
1212

13+
14+
.. automodule:: codeaudit.altairplots
15+
:members:
16+
:undoc-members:
17+
:show-inheritance:
18+

docs/apidocs/modules.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ API Reference
55
:maxdepth: 4
66

77
codeaudit
8+

docs/examples/demoscan.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "Python_Code_Audit",
33
"version": "1.6.5rc3",
4-
"generated_on": "2026-04-25 14:32",
4+
"generated_on": "2026-05-02 14:26",
55
"file_security_info": {
66
"0": {
77
"FileName": "demofile.py",

docs/examples/example_risk_heatmap.ipynb

Lines changed: 876 additions & 0 deletions
Large diffs are not rendered by default.

docs/examples/example_weakness_perfile_view.ipynb

Lines changed: 1061 additions & 0 deletions
Large diffs are not rendered by default.

src/codeaudit/altairplots.py

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def module_distribution_view(scanresult):
119119
return donut
120120

121121

122-
def make_chart(y_field, df):
122+
def _make_chart(y_field, df):
123123
"""Function to create a single bar chart with red and grey bars."""
124124

125125
# Calculate the median (or use any other threshold if needed)
@@ -160,7 +160,7 @@ def multi_bar_chart(df):
160160
"Complexity_Score",
161161
]
162162
rows = [
163-
alt.hconcat(*[make_chart(metric, df) for metric in metrics[i : i + 2]])
163+
alt.hconcat(*[_make_chart(metric, df) for metric in metrics[i : i + 2]])
164164
for i in range(0, len(metrics), 2)
165165
]
166166

@@ -245,18 +245,64 @@ def issue_overview(df):
245245

246246

247247
def complexity_heatmap(scanresult):
248-
"""Create an interactive heatmap of file complexity and size.
249-
250-
Highlights high-risk files based on complexity and lines of code,
251-
with dynamic filtering and threshold controls.
248+
"""Generate an interactive heatmap of file complexity and size.
249+
250+
This function visualizes file-level risk by combining code complexity
251+
and lines of code into a single interactive heatmap. Files are ranked
252+
and filtered to highlight the most potentially risky candidates based
253+
on a derived risk score.
254+
255+
The visualization includes:
256+
- A heatmap of file metrics ("Complexity" and "Lines")
257+
- A computed "RiskScore" used for sorting and prioritization
258+
- Interactive sliders to control threshold levels for complexity
259+
and file size
260+
- An optional toggle to display only high-risk files
261+
- Tooltip details for deeper inspection
262+
263+
Data is pre-filtered to improve usability and performance:
264+
- Top 30 files by complexity
265+
- Top 30 files by lines of code
266+
- Combined and deduplicated set, sorted by risk score
252267
253268
Args:
254-
scanresult (dict): Scan result containing "file_security_info"
255-
with file-level complexity and size metrics.
269+
scanresult (dict): Scan output containing file-level metrics.
270+
Expected structure:
271+
{
272+
"file_security_info": {
273+
"<file_id>": {
274+
"file_name": str,
275+
"Number_Of_Lines": int,
276+
"Complexity_Score": int | float,
277+
...
278+
},
279+
...
280+
}
281+
}
256282
257283
Returns:
258-
altair.Chart | str: Interactive heatmap chart, or a warning
259-
message if input is invalid.
284+
altair.Chart | str:
285+
- An Altair layered chart (heatmap + text overlay) if input is valid.
286+
- A warning message string if `scanresult` is invalid or empty.
287+
288+
Raises:
289+
KeyError: If required keys (e.g., "file_security_info") are missing.
290+
ValueError: If input data cannot be converted into a valid DataFrame.
291+
292+
Notes:
293+
- RiskScore is computed as:
294+
(Complexity / 80) + (Lines / 2000)
295+
This normalization balances the influence of both metrics.
296+
- Threshold defaults are set to 70% of the maximum observed values.
297+
- The chart is optimized for exploratory analysis rather than
298+
exhaustive dataset display.
299+
300+
Example:
301+
>>> chart = complexity_heatmap(scanresult)
302+
>>> if isinstance(chart, str):
303+
... print(chart)
304+
>>> else:
305+
... chart.show()
260306
"""
261307
if not scanresult or not isinstance(scanresult, dict):
262308
return "⚠️ No scan result available.\n\nPlease run a scan first."
@@ -596,18 +642,24 @@ def ast_nodes_overview(scanresult, width=800, height=400):
596642

597643

598644
def weaknesses_overview(scanresult):
599-
"""Create a bar chart of the most common security weaknesses.
645+
"""Generate a bar chart of the most common security weaknesses.
600646
601-
Aggregates and counts validation findings across all files in the
602-
scan result, displaying the top occurrences in a bar chart.
647+
Aggregates SAST validation findings across all scanned files and
648+
displays the most frequent issues. Designed for quick identification
649+
of recurring security patterns.
603650
604651
Args:
605-
scanresult (dict): Scan result containing "file_security_info"
606-
with SAST validation findings per file.
652+
scanresult (dict): Scan output containing "file_security_info" with
653+
per-file SAST findings. Each finding should include a "validation" field.
607654
608655
Returns:
609-
altair.Chart: Bar chart of top security weaknesses, or a fallback
610-
text chart if no data is available.
656+
altair.Chart: Bar chart of top weaknesses, or a text-based chart if
657+
input is invalid or no findings are present.
658+
659+
Notes:
660+
- Only the top 50 most frequent weaknesses are shown.
661+
- The top 5 are visually highlighted.
662+
- Returns a fallback chart instead of raising errors for invalid input.
611663
"""
612664
if not scanresult or not isinstance(scanresult, dict):
613665
return (

src/codeaudit/api_interfaces.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
22
License GPLv3 or higher.
33
4-
(C) 2025 Created by Maikel Mardjan - https://nocomplexity.com/
4+
(C) 2025 - 2026 Created by Maikel Mardjan and all contributors - https://nocomplexity.com/
55
66
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
77
@@ -48,13 +48,13 @@
4848
total_modules,
4949
)
5050

51+
5152
def version():
5253
"""Returns the version of Python Code Audit - WASM safe"""
5354
ca_version = __version__
5455
return {"name": "Python_Code_Audit", "version": ca_version}
5556

5657

57-
5858
def filescan(input_path, nosec=False):
5959
"""
6060
Scan a Python source file, a local directory, or a **PyPI package** from PyPI.org for
@@ -114,8 +114,8 @@ def filescan(input_path, nosec=False):
114114
"""
115115
file_output = {}
116116
file_path = Path(input_path)
117-
ca_version_info = {"name": "Python_Code_Audit", "version": __version__}
118-
117+
ca_version_info = {"name": "Python_Code_Audit", "version": __version__}
118+
119119
now = datetime.datetime.now()
120120
timestamp_str = now.strftime("%Y-%m-%d %H:%M")
121121
output = ca_version_info | {"generated_on": timestamp_str}
@@ -405,7 +405,7 @@ def get_default_validations():
405405

406406
def _generation_info():
407407
"""Internal function to retrieve generation info for APIs output"""
408-
ca_version_info = {"name": "Python_Code_Audit", "version": __version__}
408+
ca_version_info = {"name": "Python_Code_Audit", "version": __version__}
409409
now = datetime.datetime.now()
410410
timestamp_str = now.strftime("%Y-%m-%d %H:%M")
411411
output = ca_version_info | {"generated_on": timestamp_str}

src/codeaudit/corecli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
22
License GPLv3 or higher.
33
4-
(C) 2025 Created by Maikel Mardjan - https://nocomplexity.com/
4+
(C) 2025 - 2026 Created by Maikel Mardjan and all contributors - https://nocomplexity.com/
55
66
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
77

0 commit comments

Comments
 (0)