codeaudit 0.5.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
codeaudit/simple.css ADDED
@@ -0,0 +1,200 @@
1
+ /* Reset some default styles for consistency */
2
+ /* GPLv3 - (c) Maikel Mardjan - simple works fine */
3
+
4
+ * {
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ /* Base container */
9
+ .container {
10
+ max-width: 1200px;
11
+ margin: 0 auto;
12
+ padding: 0 10px;
13
+ }
14
+
15
+ /* Remove default margins/paddings */
16
+ body,
17
+ h1,
18
+ h2,
19
+ h3,
20
+ p {
21
+ margin: 0;
22
+ padding: 0;
23
+ }
24
+
25
+ /* Body base styles */
26
+ body {
27
+ font-family: Arial, Helvetica, sans-serif;
28
+ background-color: #FFFFFF;
29
+ color: #333;
30
+ line-height: 1.6;
31
+ padding: 30px;
32
+ }
33
+
34
+ /* Headings */
35
+ h1, h2, h3 {
36
+ color: #ff0000; /* Set heading text color to red */
37
+ }
38
+
39
+ /* Headings */
40
+ h1 {
41
+ font-size: 36px;
42
+ margin-bottom: 20px;
43
+ }
44
+
45
+ h2 {
46
+ font-size: 28px;
47
+ margin-bottom: 15px;
48
+ }
49
+
50
+ h3 {
51
+ font-size: 22px;
52
+ margin-bottom: 10px;
53
+ }
54
+
55
+ /* Paragraphs and links */
56
+ p {
57
+ margin-bottom: 15px;
58
+ }
59
+
60
+ a {
61
+ color: black;
62
+ text-decoration: none;
63
+ }
64
+
65
+ a:hover {
66
+ text-decoration: underline;
67
+ }
68
+
69
+ /* Responsive images */
70
+ img {
71
+ max-width: 100%;
72
+ height: auto;
73
+ }
74
+
75
+ /* Lists */
76
+ ul,
77
+ ol {
78
+ margin-left: 20px;
79
+ margin-bottom: 15px;
80
+ }
81
+
82
+ /* Buttons */
83
+ .button {
84
+ display: inline-block;
85
+ padding: 10px 20px;
86
+ background-color: #007bff;
87
+ color: #fff;
88
+ text-decoration: none;
89
+ border: none;
90
+ cursor: pointer;
91
+ border-radius: 5px;
92
+ }
93
+
94
+ .button:hover {
95
+ background-color: #0056b3;
96
+ }
97
+
98
+ /* Footer */
99
+ footer {
100
+ background-color: #333;
101
+ color: #fff;
102
+ text-align: center;
103
+ padding: 10px;
104
+ }
105
+
106
+ /* Tables */
107
+ table {
108
+ border-collapse: collapse;
109
+ width: 100%;
110
+ }
111
+
112
+ th,
113
+ td {
114
+ border: 1px solid #d8d8dd;
115
+ padding: 8px;
116
+ text-align: left;
117
+ }
118
+
119
+ /* Media queries for responsiveness */
120
+ @media (max-width: 768px) {
121
+ header {
122
+ font-size: 24px;
123
+ padding: 15px;
124
+ }
125
+
126
+ h1 {
127
+ font-size: 28px;
128
+ }
129
+
130
+ h2 {
131
+ font-size: 24px;
132
+ }
133
+
134
+ h3 {
135
+ font-size: 20px;
136
+ }
137
+
138
+ .container {
139
+ padding: 0 10px;
140
+ }
141
+ }
142
+
143
+ /* Altair (Vega-Embed) tweaks */
144
+ #vis.vega-embed {
145
+ width: 100%;
146
+ display: flex;
147
+ }
148
+
149
+ #vis.vega-embed details,
150
+ #vis.vega-embed details summary {
151
+ position: relative;
152
+ }
153
+
154
+ /* Code blocks */
155
+ pre {
156
+ font-size: 1.25em;
157
+ border-radius: 5px;
158
+ overflow-x: auto;
159
+ width: 100%;
160
+ max-width: 600px;
161
+ }
162
+
163
+ /* Base style for Python code blocks */
164
+ .language-python {
165
+ background-color: #2d2d2d; /* dark gray background */
166
+ color: #f8f8f2; /* light text */
167
+ font-family: Consolas, Monaco, 'Courier New', monospace;
168
+ font-size: 14px;
169
+ line-height: 1.5;
170
+ padding: 1em;
171
+ border-radius: 6px;
172
+ display: block;
173
+ overflow-x: auto;
174
+ white-space: pre;
175
+ }
176
+
177
+ footer {
178
+ background-color: #FFFFFF;
179
+ color: red;
180
+ text-align: center;
181
+ padding: 10px;
182
+ }
183
+
184
+ .json-display {
185
+ background-color: #2d2d2d; /* dark gray background */
186
+ color: #f8f8f2; /* light text */
187
+ white-space: pre-wrap; /* Preserves indentation & wraps lines */
188
+ word-wrap: break-word; /* Breaks long words */
189
+ overflow-wrap: break-word; /* Modern equivalent */
190
+ font-family: Consolas, Monaco, 'Courier New', monospace;
191
+ font-size: 14px;
192
+ line-height: 1.5;
193
+ padding: 1em;
194
+
195
+ }
196
+
197
+
198
+ /* nocxdataframe for table css */
199
+
200
+
codeaudit/totals.py ADDED
@@ -0,0 +1,137 @@
1
+ """
2
+ License GPLv3 or higher.
3
+
4
+ (C) 2025 Created by Maikel Mardjan - https://nocomplexity.com/
5
+
6
+ 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.
7
+
8
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
9
+
10
+ You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
11
+
12
+ Simple checker reporting #source code, #comments in Python files
13
+ """
14
+
15
+ import ast
16
+ import warnings
17
+
18
+ from codeaudit.filehelpfunctions import read_in_source_file , get_filename_from_path , collect_python_source_files
19
+ from codeaudit.complexitycheck import calculate_complexity , count_static_warnings_in_file
20
+
21
+
22
+ def count_ast_objects(source):
23
+ """
24
+ Counts AST nodes and objects.
25
+ This gives an indication of complexity and code maintainability.
26
+ Suppresses SyntaxWarnings like invalid escape sequences.
27
+ """
28
+ with warnings.catch_warnings():
29
+ warnings.simplefilter("ignore", category=SyntaxWarning)
30
+ tree = ast.parse(source)
31
+
32
+ ast_nodes = 0
33
+ ast_functions = 0
34
+ ast_modules = 0
35
+ ast_classes = 0
36
+
37
+ for node in ast.walk(tree):
38
+ if hasattr(node, 'lineno') and isinstance(node, (ast.stmt, ast.Expr)):
39
+ ast_nodes += 1
40
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
41
+ ast_functions += 1
42
+ if isinstance(node, (ast.Import, ast.ImportFrom)):
43
+ ast_modules += 1
44
+ if isinstance(node, ast.ClassDef):
45
+ ast_classes += 1
46
+
47
+ result = {
48
+ 'AST_Nodes': ast_nodes,
49
+ 'Modules': ast_modules,
50
+ 'Functions': ast_functions,
51
+ 'Classes': ast_classes
52
+ }
53
+
54
+ return result
55
+
56
+
57
+ def count_comment_lines(source):
58
+ """Counts lines with comments and all lines inside triple-double-quoted strings """
59
+ comment_lines = set()
60
+ lines = source.splitlines()
61
+ in_triple_double = False
62
+
63
+ for i, line in enumerate(lines, start=1):
64
+ stripped = line.strip()
65
+ # Check for triple-double-quote boundaries
66
+ if stripped.count('"""') == 1:
67
+ # Start or end of a multiline string
68
+ in_triple_double = not in_triple_double
69
+ comment_lines.add(i) # Count this line
70
+ elif stripped.count('"""') >= 2:
71
+ # Triple quotes open and close on the same line
72
+ comment_lines.add(i)
73
+ elif in_triple_double:
74
+ comment_lines.add(i)
75
+ elif line.startswith('#'):
76
+ # Regular comment - note that inline comment are NOT counted as comment lines
77
+ comment_lines.add(i)
78
+ result = { 'Comment_Lines' : len(comment_lines)}
79
+ return result
80
+
81
+ def count_lines_iterate(filepath):
82
+ """
83
+ Counts the number of lines in a file by iterating through the file object.
84
+ This method is memory-efficient for large files.
85
+ """
86
+ count = 0
87
+ try:
88
+ with open(filepath, 'r') as f:
89
+ for line in f:
90
+ count += 1
91
+ return count
92
+ except FileNotFoundError:
93
+ print(f"Error: File not found at {filepath}")
94
+ return -1
95
+ except Exception as e:
96
+ print(f"An error occurred: {e}")
97
+ return -1
98
+
99
+
100
+
101
+ def get_statistics(directory):
102
+ """Get codeaudit statistics from source files in a directory"""
103
+ files_to_check = collect_python_source_files(directory)
104
+ total_result = []
105
+ for python_file in files_to_check:
106
+ result = overview_per_file(python_file)
107
+ total_result.append(result)
108
+ return total_result
109
+
110
+ def overview_per_file(python_file):
111
+ """gets the overview per file."""
112
+ result ={}
113
+ source = read_in_source_file(python_file)
114
+ name_of_file = get_filename_from_path (python_file)
115
+ name_dict = { 'FileName' : name_of_file}
116
+ file_location = {'FilePath' : python_file}
117
+ number_of_lines = count_lines_iterate(python_file)
118
+ lines = {'Number_Of_Lines' : number_of_lines}
119
+ complexity_score = calculate_complexity(source)
120
+ complexity = {'Complexity_Score' : complexity_score}
121
+ warnings = count_static_warnings_in_file (python_file)
122
+ result = name_dict | file_location | lines | count_ast_objects(source) | count_comment_lines(source) | complexity | warnings # merge the dicts
123
+ return result
124
+
125
+
126
+
127
+ def overview_count(df):
128
+ """returns a dataframe with simple overview of all files"""
129
+ columns_to_sum = ['Number_Of_Lines', 'AST_Nodes', 'Modules', 'Functions', 'Classes', 'Comment_Lines']
130
+ df_totals = df[columns_to_sum].sum().to_frame().T # .T to make it a single row
131
+ total_number_of_files = df.shape[0]
132
+ df_totals.insert(0, 'Number_Of_Files', total_number_of_files) #insert new column as first colum
133
+ median_complexity = round(df['Complexity_Score'].mean(), 1)
134
+ df_totals['Median_Complexity'] = median_complexity
135
+ maximum_complexity = df['Complexity_Score'].max()
136
+ df_totals['Maximum_Complexity'] = maximum_complexity
137
+ return df_totals
@@ -0,0 +1,156 @@
1
+ Metadata-Version: 2.4
2
+ Name: codeaudit
3
+ Version: 0.5.3
4
+ Summary: Simplified static security checks for Python
5
+ Project-URL: Documentation, https://github.com/nocomplexity/codeaudit#readme
6
+ Project-URL: Issues, https://github.com/nocomplexity/codeaudit/issues
7
+ Project-URL: Source, https://github.com/nocomplexity/codeaudit
8
+ Author-email: Maikel Mardjan <mike@bm-support.org>
9
+ License-Expression: GPL-3.0-or-later
10
+ License-File: LICENSE.txt
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Python: >=3.8
16
+ Requires-Dist: altair>=5.5
17
+ Requires-Dist: fire>=0.7.0
18
+ Requires-Dist: pandas>=2.3
19
+ Description-Content-Type: text/markdown
20
+
21
+ # codeaudit
22
+
23
+ [![PyPI - Version](https://img.shields.io/pypi/v/codeaudit.svg)](https://pypi.org/project/codeaudit)
24
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/codeaudit.svg)](https://pypi.org/project/codeaudit)
25
+
26
+ Codeaudit - A modern Python source code analyzer based on distrust.
27
+
28
+ Codeaudit is a tool designed to find security issues in Python code. This static application security testing (SAST) tool has great features to simplify the necessary security tasks and make it fun and easy.
29
+
30
+ This tool is created for:
31
+ * Anyone who want or must check security risks with Python programs.
32
+ * Anyone who loves to create functionality using Python. So not only professional programs , but also occasional Python programmers or programmers who are used to working with other languages.
33
+ * Anyone who wants an easy way to get insight in possible security risks Python programs.
34
+
35
+
36
+ > [!WARNING]
37
+ > Codeaudit is still is currently in *beta status*. There are still bugs in the software that need to be fixed. Consider [contributing](CONTRIBUTING.md) to make Codeaudit a cool modern Python SAST tool. Codeaudit is currently in a thorough testing period and changes and fixes are frequently applied.
38
+
39
+ ## Features
40
+
41
+ Codeaudit has the following features:
42
+
43
+ * Detecting and reporting potential vulnerabilities of from all Python files collected in a directory. This is a must **do** check when researching python packages on possible security issues.
44
+
45
+ * Detect and reports complexity and statistics relevant for security per Python file or from Python files found in a directory.
46
+
47
+ * Codeaudit implements a light weight [cyclomatic complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity) using Python’s Abstract Syntax Tree module. The codeaudit implemented check is by far good enough for determining security risks in Python files very quick!
48
+
49
+
50
+ * Detect and reports which module are used within a Python file. Also vulnerability information found from used external modules is shown.
51
+
52
+ * Detecting and reporting potential vulnerability issues within a Python file. Per detected issue the line number shown, with the lines that *could* cause a security issue.
53
+
54
+ * All output is saved in simple static HTML-reports. These reports can be examined in every browser.
55
+
56
+
57
+ > [!IMPORTANT]
58
+ > Codeaudit uses the Python's Abstract Syntax Tree (AST) to get robust and reliable result. Using the Python AST makes contextual Vulnerability Detection possible and false positive are minimized.
59
+
60
+
61
+ ## Installation
62
+
63
+ ```console
64
+ pip install codeaudit
65
+ ```
66
+
67
+ or use:
68
+
69
+ ```bash
70
+ pip install -U codeaudit
71
+ ```
72
+
73
+ If you have installed Codeaudit in the past and want to make sure you use the latest checks and features.
74
+
75
+ ## Usage
76
+
77
+ After installation you can get an overview of all implemented commands. Just type in your terminal:
78
+
79
+ ```text
80
+ codeaudit
81
+ ```
82
+
83
+ This will show all commands:
84
+
85
+ ```text
86
+ --------------------------------------------------
87
+ _____ _ _ _ _
88
+ / ____| | | | (_) |
89
+ | | ___ __| | ___ __ _ _ _ __| |_| |_
90
+ | | / _ \ / _` |/ _ \/ _` | | | |/ _` | | __|
91
+ | |___| (_) | (_| | __/ (_| | |_| | (_| | | |_
92
+ \_____\___/ \__,_|\___|\__,_|\__,_|\__,_|_|\__|
93
+ --------------------------------------------------
94
+
95
+ Codeaudit - Modern Python source code analyzer based on distrust.
96
+
97
+ Commands to evaluate Python source code:
98
+ Usage: codeaudit COMMAND [PATH or FILE] [OUTPUTFILE]
99
+
100
+ Depending on the command, a directory or file name must be specified. The output is a static HTML file to be examined in a browser. Specifying a name for the output file is optional.
101
+
102
+ Commands:
103
+ overview Reports Complexity and statistics per Python file from a directory.
104
+ modulescan Reports module information per file.
105
+ filescan Reports potential security issues for a single Python file.
106
+ directoryscan Reports potential security issues for all Python files found in a directory.
107
+ checks Generate an HTML report of all implemented codeaudit security checks.
108
+ version Prints the module version. Use [-v] [--v] [-version] or [--version].
109
+
110
+ Use the Codeaudit documentation to check the security of Python programs and make your Python programs more secure!
111
+ Check https://simplifysecurity.nocomplexity.com/
112
+ ```
113
+
114
+ ## Example
115
+
116
+ By running the `codeaudit filescan` command, detailed security information is determined for a Python file based on more than **60 validations** implemented.
117
+
118
+ The `codeaudit filescan` command shows all **potential** security issues that are detected in the source file in a HTML-report.
119
+
120
+ Per line a the in construct that can cause a security risks is shown, along with the relevant code lines where the issue is detected.
121
+
122
+ To scan a Python file on possible security issues, do:
123
+
124
+ ```
125
+ codeaudit filescan ./codeaudit/tests/validationfiles/allshit.py
126
+ Codeaudit report file created!
127
+ Check the report file: file:///home/jamesbrown/tmp/codeaudit-report.html
128
+ ```
129
+
130
+ ![Example view of filescan report](filescan.png)
131
+
132
+
133
+ ## Contributing
134
+
135
+ All contributions are welcome! Think of corrections on the documentation, code or more and better tests.
136
+
137
+ Simple Guidelines:
138
+
139
+ * Questions, Feature Requests, Bug Reports please use on the Github Issue Tracker.
140
+
141
+ **Pull Requests are welcome!**
142
+
143
+ When you contribute to Codeaudit, your contributions are made under the same license as the file you are working on.
144
+
145
+
146
+ > [!NOTE]
147
+ > This is an open community driven project. Contributors will be mentioned in the documentation.
148
+
149
+ We adopt the [Collective Code Construction Contract(C4)](https://rfc.zeromq.org/spec/42/) to streamline collaboration.
150
+
151
+ ## License
152
+
153
+
154
+ `codeaudit` is distributed under the terms of the [GPL-3.0-or-later](https://spdx.org/licenses/GPL-3.0-or-later.html) license.
155
+
156
+
@@ -0,0 +1,19 @@
1
+ codeaudit/__about__.py,sha256=rgYySBYwOF29ZZo8euSGDDMVqO7c0NkbOpyk6Sq-zVY,144
2
+ codeaudit/__init__.py,sha256=YGs6qU0BVHPGtXCS-vfBDLO4TOfJDLTWMgaFDTmi_Iw,157
3
+ codeaudit/altairplots.py,sha256=VvlxOwYJS40TerP0Wee1KjOF1sdVTyBtkxDIaNF7VUc,2046
4
+ codeaudit/checkmodules.py,sha256=GdGyF5wTdSipkCCdrTTRqRM0et2G5Dcv-pTetr5nbks,3505
5
+ codeaudit/codeaudit.py,sha256=LYaCMVXyEncq-zqBYAvUrlu7ivgQMBdgWJjtO-h2vX4,3606
6
+ codeaudit/complexitycheck.py,sha256=fMwDjFcbqJpqgF7uh5f29XqmacUsd0lOO5tHje2fiVM,3735
7
+ codeaudit/filehelpfunctions.py,sha256=RzN8aW2el-WG8ocAUVomGLzRgp9AVdcjnpw92d93XVU,3739
8
+ codeaudit/htmlhelpfunctions.py,sha256=sps5voMc6v_GX5sRhxiS0w2kzdhDkH7Wqt9MZTTCjvk,2982
9
+ codeaudit/issuevalidations.py,sha256=bluJKFbs3fEkzR4hzwZWQXTJBxyCpNTNgtaq-eutVfw,5594
10
+ codeaudit/reporting.py,sha256=h0751seo_qRoY8dEpVsQDlG51jDLsaK3uBcqSFqXHJU,19723
11
+ codeaudit/security_checks.py,sha256=n_FMF2b--vpkX3E4wvFcXr9pJO-_sdUq2NHuj6mvMvw,2208
12
+ codeaudit/simple.css,sha256=QyqcZKLqj4JXByTskabrOEJYfn2L2o8XfTLyeO1RxeI,3210
13
+ codeaudit/totals.py,sha256=JnPh47NJh1X7nzz6K6gyh1UbCnNRQlV74Wu-cd63ZMU,5297
14
+ codeaudit/data/sastchecks.csv,sha256=8bG0jaiG2bHYYOl1kApF4K1P1-aTG3fK0X-lU5J72Qw,6533
15
+ codeaudit-0.5.3.dist-info/METADATA,sha256=EgviHwzybyuL44EdiOcPl-unoaf3HjCB6KE0rpUDLaA,6563
16
+ codeaudit-0.5.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
+ codeaudit-0.5.3.dist-info/entry_points.txt,sha256=7w6I8zii62nJHIIF30CRP5g1z8enMqF1pZEDdlw4HcQ,55
18
+ codeaudit-0.5.3.dist-info/licenses/LICENSE.txt,sha256=-5gWaMGKJ54oX8TYP7oeg2zITdTapzyWl9PP0tispuA,34674
19
+ codeaudit-0.5.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ codeaudit = codeaudit.codeaudit:main