CodeLens is a production-quality static code analysis platform that reviews Python source code (without executing it) using Python's Abstract Syntax Tree (AST). It calculates cyclomatic complexity, audits security vulnerabilities, verifies PEP-8 compliance, detects dead code blocks, standardizes structural duplication, and offers AI-driven explanations and refactoring suggestions.
Featuring a Modern responsive dashboard, CodeLens allows developers to drag and drop single files or repository zip packages, explore codebase folders in an interactive tree view, filter warning highlights by severity, search issue records, and review side-by-side refactored code blocks generated by AI.
Below is the design structure of CodeLens, showing the pipeline flow from source ingestion down to DB persistence and user interfaces:
graph TD
User([User / Developer]) -->|Upload File/Repo or run CLI| Entry[CodeLens Entrypoints]
subgraph Ingestion Layer
Entry -->|REST requests| REST[FastAPI REST API]
Entry -->|Console inputs| CLI[Codelens CLI Tool]
end
REST -->|Extract and filter| Scanner[Repository Zip Scanner]
REST -->|Source String| Parser[AST Parser]
CLI -->|Recursive Walk| Parser
Scanner -->|Individual Files| Parser
Parser -->|ast.parse| Engine[Analysis Engine Pipeline]
subgraph Rule Execution Pipeline
Engine --> Rule1[Imports Analyzer]
Engine --> Rule2[Variables Analyzer]
Engine --> Rule3[Dead Code Analyzer]
Engine --> Rule4[Complexity Analyzer]
Engine --> Rule5[Security Analyzer]
Engine --> Rule6[Duplicate Analyzer]
Engine --> Rule7[Naming Analyzer]
Engine --> Rule8[Docstring Analyzer]
Engine --> Rule9[Style Analyzer]
end
Rule1 & Rule2 & Rule3 & Rule4 & Rule5 & Rule6 & Rule7 & Rule8 & Rule9 --> Agg[Report Aggregator]
Agg -->|Calculate scores / counts| Stats[Stats Generator]
Stats -->|Explain Request| AI[Gemini AI Explanation Engine]
AI -->|Fallback if Offline| Heuristics[Local Heuristic Database]
Stats -->|SQLAlchemy ORM| DB[(PostgreSQL / SQLite)]
DB --> View[Dashboard Interface / Swagger / CLI Output]
This sequence diagram outlines the end-to-end execution of a repository upload, analysis, and dashboard visualization:
sequenceDiagram
autonumber
actor Dev as Developer
participant API as FastAPI App
participant ZH as Zip Handler
participant P as AST Parser
participant AE as Analysis Engine
participant RS as Report Service
participant DB as Database
participant UI as Dashboard UI
Dev->>API: POST /api/v1/analyze/repository (Upload ZIP)
activate API
API->>ZH: extract_python_files_from_zip(bytes)
activate ZH
ZH-->>API: Dict[filepath, code_content]
deactivate ZH
loop For each file
API->>P: parse_ast(code, filename)
activate P
P-->>API: AST Tree
deactivate P
API->>AE: analyze_source_code(code, filepath)
activate AE
AE->>AE: Run 9 rules on AST
AE-->>API: File Metrics & List of Issues
deactivate AE
end
API->>RS: calculate_scan_metrics(scan)
activate RS
RS-->>API: Health Score, Totals, Trend History
deactivate RS
API->>DB: Save Scan, FileAnalysis, and Issues
activate DB
DB-->>API: Transaction Success
deactivate DB
API-->>Dev: Return Scan Summary JSON
deactivate API
UI->>API: GET /api/v1/report/{id} (Fetch Report)
activate API
API->>DB: Query Scan details
DB-->>API: Scan records
API-->>UI: Return Full Scan Report JSON
deactivate API
UI->>UI: Render Directory Tree & Highlight Code Issues
The overall Project Health Score starts at 100.0% and is reduced by deductions for each issue found, weighted by the issue's severity:
Where severity deduction weights are:
- 🔴 CRITICAL:
15points deduction (e.g. Hardcoded secrets, dangerous dynamic execution vulnerabilities) - 🟠 HIGH:
10points deduction (e.g. SQL Injection, Unreachable statements, critical complexity) - 🟡 MEDIUM:
5points deduction (e.g. Wildcard imports, unused variables, medium complexity) - 🔵 LOW:
2points deduction (e.g. Style violations, missing docstrings, naming convention warnings)
McCabe Cyclomatic complexity measures the number of linearly independent paths through a function's source code:
Where
- Conditional statements (
ast.If,ast.While,ast.For,ast.AsyncFor) - Exception catch blocks (
ast.ExceptHandler) - Boolean operators (
ast.And,ast.Or/ast.BoolOp) - Comprehensions and generators (
ast.ListComp,ast.SetComp,ast.DictComp,ast.GeneratorExp)
Instead of checking raw text or lines (which can be bypassed by renaming variables or rearranging spacing), CodeLens normalizes function syntax trees:
Function Source Code
│
▼
AST Parse (ast.parse)
│
▼
Normalize Names (Rename local variables & parameters to v0, v1, etc.)
│
▼
Strip Metadata (Remove docstrings, string constants, comments, and decorator wrappers)
│
▼
Unparse to Code (Convert canonical AST structure back to source text)
│
▼
Compare Similarity (difflib.SequenceMatcher ratio matches >= 80%)
Here are visual examples of the CodeLens workspace in action (saved inside the assets/img/ folder):
| Dashboard KPI View | Interactive Sidebar Directory | Code Panel & Severity Filters |
|---|---|---|
![]() |
![]() |
![]() |
| AI Refactoring Drawer | Developer CLI Output | Swagger API Documentation |
|---|---|---|
![]() |
![]() |
![]() |
- AST-Based Static Analysis Rules:
- Imports: Unused, wildcard (
from x import *), and duplicate imports. - Variables: Unused local variables, parameters, shadowing built-ins, and reassignments.
- Dead Code: Statements after return/raise/break/continue and constant conditional blocks (
if False:). - Complexity: McCabe Cyclomatic Complexity per function and averages.
- Security: Exec/eval dynamic calls, unsafe pickle deserialization, SQL string injection, and hardcoded credentials.
- Duplicate Code: Normalizes variable scopes and compares function blocks for similarity (above 80%/90%/95% ratios).
- PEP-8 Naming: Class names (PascalCase), functions/locals (snake_case), and globals (UPPER_CASE).
- Documentation: Audits missing docstrings for modules, classes, and public functions.
- Code Style: Nesting depths greater than 3, lines exceeding 88 characters, and spacing issues.
- Imports: Unused, wildcard (
- AI explanation with Google Gemini:
- Interfaces with Google Gemini (e.g.
gemini-1.5-flash) to generate detailed markdown reasons and side-by-side refactored scripts. - Falls back gracefully to a robust local heuristic engine containing pre-constructed code guides if offline or without keys.
- Interfaces with Google Gemini (e.g.
- Professional Glassmorphic SPA Dashboard:
- Interactive Sidebar Tree: Parses files list recursively into collapsible directory folders.
- Search & Filters: Search box filters files and issue text, and severity buttons filter editor warnings.
- Trend Analysis: Sparkline SVG displays health score progress over previous scans.
- Repository Summary Stats: KPI summary block mapping total files, lines of code, functions, and class declarations.
- Colorized Developer CLI:
- Scan single python scripts or complete project packages locally.
- Colorizes printouts by severity and returns exit code 1 on low scores or critical failures (ideal for CI/CD checks).
Most legacy tools rely on regular expressions to audit code. CodeLens uses an Abstract Syntax Tree (AST) parser. Here is why:
| Metric / Check | Regular Expressions (Regex) | Abstract Syntax Tree (AST) |
|---|---|---|
| Parsing Method | String pattern matching (ignores context). | Parses source into hierarchical node structures. |
| Scope Detection | Fails to distinguish between global, class, and local function variable scopes. | Easily differentiates naming scopes and detects variable shadowing. |
| Syntax Validity | Scans broken or structurally invalid python files. | Ensures syntactical compliance before execution (validates compiler parser). |
| Control Flow Auditing | Cannot trace execution order or detect unreachable branches after exits. | Maps branches recursively to find unreachable nodes (e.g., statements after return). |
| Complexity Calculation | Estimates logic density by counting keyword occurrences. | Calculates exact McCabe complexity using code block node counts. |
| Normalizing Code | Unable to compare structure if variable names or comments change. | normalizes names and strips docstrings/line spacing for exact duplication reviews. |
CodeLens monitors 18 unique static code quality checks classified by severity:
| Rule ID | Rule Name | Description | Severity |
|---|---|---|---|
| unused_import | Unused Import | Detects module imports that are never loaded. | LOW |
| wildcard_import | Wildcard Import | Flags namespace pollution from from module import *. |
MEDIUM |
| duplicate_import | Duplicate Import | Flags redundant duplicate import statements. | LOW |
| unused_variable | Unused Local / Param | Detects local assignments or parameters that are never read. | MEDIUM |
| reassigned_variable | Reassigned Variable | Variable assigned to a new value without reading first. | LOW |
| shadowed_variable | Shadowed Variable | Local variables overriding built-in names (e.g., list). |
MEDIUM |
| unreachable_code | Unreachable Statements | Code written directly after return, raise, break, or continue. | HIGH |
| dead_code_branch | Dead Condition Branch | Checks conditions resolving to constant falsy expressions. | HIGH |
| high_complexity | Critical Complexity | Cyclomatic complexity count exceeds 10. | HIGH |
| medium_complexity | Medium Complexity | Cyclomatic complexity count between 6 and 10. | MEDIUM |
| security_vulnerability | Dangerous Methods | Execution of exec(), eval(), os.system(), yaml.load() (unsafe). | CRITICAL |
| hardcoded_secret | Hardcoded Secret | Assigning plain secrets to keys, passwords, or tokens. | CRITICAL |
| sql_injection | Dynamic SQL Injection | Concatenating dynamic query strings inside execute commands. | HIGH |
| duplicate_code | Duplicate Functions | Structurally similar function trees (ratio >= 80%). | MEDIUM |
| naming_convention | PEP-8 Conventions | PascalCase classes, snake_case functions and variables. | LOW |
| missing_docstring | Missing Documentation | Undocumented classes, modules, or public methods. | LOW |
| style_violation | Code Nesting / Length | Lines exceeding 88 characters or nesting depth > 3. | LOW |
CodeLens exposes RESTful API endpoints for external reviews and CI tools:
Analyzes a single Python file.
- Request Payload:
multipart/form-datafile: UploadFile (Python source file)project_name: str (Defaults to "Default Project")
- Response Example (HTTP 200):
{
"id": 12,
"project_id": 1,
"scan_time": "2026-06-29T03:00:00Z",
"total_files": 1,
"total_lines": 42,
"total_functions": 3,
"total_classes": 1,
"health_score": 93.0,
"status": "completed"
}Analyzes multiple Python files packed inside a zip folder.
- Request Payload:
multipart/form-datafile: UploadFile (ZIP archive containing files)project_name: str
- Response Example (HTTP 200):
{
"id": 13,
"project_id": 2,
"scan_time": "2026-06-29T03:01:00Z",
"total_files": 12,
"total_lines": 1482,
"total_functions": 124,
"total_classes": 18,
"health_score": 87.5,
"status": "completed"
}Returns dashboard metrics for the scan.
- Response Example (HTTP 200):
{
"scan_id": 13,
"project_id": 2,
"scan_time": "2026-06-29T03:01:00Z",
"status": "completed",
"total_files": 12,
"total_lines": 1482,
"total_functions": 124,
"total_classes": 18,
"health_score": 87.5,
"total_issues": 31,
"critical_issues": 1,
"high_issues": 3,
"medium_issues": 12,
"low_issues": 15,
"security_score": 85.0,
"average_complexity": 3.42,
"max_complexity": 12.0,
"maintainability_score": 78.4,
"duplicate_percentage": 16.7,
"unused_imports": 4,
"unused_variables": 8,
"duplicate_functions": 2,
"issue_types": {
"unused_import": 4,
"unused_variable": 8,
"high_complexity": 1,
"style_violation": 14,
"security_vulnerability": 1,
"sql_injection": 3
},
"trend_history": [
{
"scan_id": 10,
"health_score": 72.0,
"scan_time": "2026-06-28T12:00:00Z"
},
{
"scan_id": 11,
"health_score": 81.2,
"scan_time": "2026-06-28T18:00:00Z"
},
{ "scan_id": 13, "health_score": 87.5, "scan_time": "2026-06-29T03:01:00Z" }
]
}Generates Gemini AI explanation for an issue.
- Request Payload (
application/json):
{
"issue_id": 452
}- Response Example (HTTP 200):
{
"explanation": "### Why is this an issue?\nDynamic SQL execution using string formatting creates SQL Injection vulnerabilities. Malicious input values can modify the execution structure of the query, exposing schema configurations.\n\n### Implications\n* Data leakage\n* Schema alterations",
"refactored_code": "# Use parameterized placeholders:\nquery = \"SELECT * FROM users WHERE id = %s\"\ncursor.execute(query, (user_id,))"
}CodeLens is designed to perform recursive codebase reviews extremely quickly. The following benchmarks were conducted on a developer environment (Intel Core i7 12th Gen, 16GB RAM):
| Project Target | Total Files | Total Lines (LOC) | Scan Execution Time | Avg Memory Usage | Output Health Rating |
|---|---|---|---|---|---|
| FastAPI Core App | 18 | 2,120 | 0.28 seconds | ~52 MB | 92.4% |
| Django (subset) | 240 | 36,400 | 1.84 seconds | ~74 MB | 86.2% |
| Request Library | 64 | 9,800 | 0.54 seconds | ~58 MB | 89.1% |
Ensure Python 3.12+ is installed.
# Install dependencies
pip install -r requirements.txt
# Start the uvicorn ASGI local server (defaults to local SQLite database)
python -m uvicorn app.main:app --reloadNavigate to http://localhost:8000/ to open the interface.
Configure a .env file in the root folder:
GEMINI_API_KEY=your_gemini_api_key_here
GEMINI_MODEL=gemini-1.5-flash
# Optional: To use Postgres instead of SQLite (default: sqlite:///./codelens.db)
# DATABASE_URL=postgresql://user:password@localhost:5432/dbnameTo build and spin up the FastAPI application alongside a PostgreSQL container:
docker-compose -f docker/docker-compose.yml up --buildThis deploys the application on http://localhost:8000/.
You can review code directly from your terminal using codelens.py:
# Scan a single file
python codelens.py app/main.py
# Scan a directory recursively (ignoring virtual environments/git folders)
python codelens.py .
# Fail the execution (exit code 1) if health score drops below 90%
python codelens.py . --min-health 90.0
# Fail the execution if any CRITICAL or HIGH issues are found
python codelens.py . --fail-on-criticalExecute the pytest suite (with SQLite isolation configurations):
# Run all tests
pytest -v
# Run tests and verify code coverage (targeted coverage: >80%)
pytest -v --cov=app tests/CodeLens has a clear expansion path to become a fully-fledged code quality framework:
- VS Code Extension: Integrate the CodeLens analysis engine directly as an IDE extension highlighting issues inline.
- GitHub PR Reviewer: Launch a GitHub App that scans PR commits and posts comments on lines containing violations.
- SARIF Export Support: Enable outputting scans in Static Analysis Results Interchange Format (SARIF) for integration into SonarQube or GitHub Advanced Security.
- Multi-language Support: Add parsing rules for TypeScript and Go using Tree-sitter.
- Incremental Analysis: Cache AST hashes to analyze only modified files on subsequent runs, speeding up pipeline scanning.
- Git Pre-commit Hooks: Prevent commits if local scans fail health thresholds.





