I needed a fast way to audit legacy Python scripts for obvious bugs and anti-patterns without spinning up a full static-analysis pipeline. In this guide I will walk through a small CLI tool that sends source files to an LLM and returns a structured JSON report of issues, built on Oxlo.ai so long files do not inflate the cost.
What you'll need
- Python 3.10 or newer
- The OpenAI SDK:
pip install openai - An Oxlo.ai API key from https://portal.oxlo.ai
Step 1: Bootstrap the script
Create analyzer.py and initialize the Oxlo.ai client. Oxlo.ai is fully OpenAI SDK compatible, so the only change is the base URL.
from openai import OpenAI
import json
import sys
from pathlib import Path
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_OXLO_API_KEY" # get yours at https://portal.oxlo.ai
)
Step 2: Write the system prompt
The prompt forces the model to emit only JSON and defines the three categories we care about: bugs, security risks, and refactoring candidates.
SYSTEM_PROMPT = '''You are a senior code reviewer. Analyze the provided code and return a single JSON object with exactly these keys:
- "bugs": a list of objects, each with "line" (int), "severity" ("low"|"medium"|"high"), and "description" (string).
- "security": a list of objects with the same schema.
- "refactors": a list of objects with the same schema.
Do not include markdown fences, explanations, or any text outside the JSON object.'''
Step 3: Load the target code
We read the file and build the user message. I keep the message minimal so the model focuses on the code itself.
def load_code(path: str) -> str:
return Path(path).read_text(encoding="utf-8")
def build_user_message(code: str, filename: str) -> str:
return f"Filename: {filename}\n\n
```python\n{code}\n```
\n\nReturn the JSON review."
Step 4: Send the request
I use Llama 3.3 70B because it handles long contexts reliably. If you need deeper reasoning for complex algorithms you can swap the model to qwen-3-32b or deepseek-v3.2 without changing any other code. Because Oxlo.ai charges per request rather than per token, analyzing a 400-line module costs the same as a 10-line snippet. See https://oxlo.ai/pricing for current tiers.
def analyze_file(path: str):
code = load_code(path)
user_message = build_user_message(code, Path(path).name)
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
response_format={"type": "json_object"},
temperature=0.2,
)
raw = response.choices[0].message.content
return json.loads(raw)
Step 5: Wrap it in a CLI
Add a small main block that pretty-prints the results.
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python analyzer.py <file.py>")
sys.exit(1)
target = sys.argv[1]
result = analyze_file(target)
for category in ["bugs", "security", "refactors"]:
items = result.get(category, [])
print(f"\n{category.upper()} ({len(items)})")
for item in items:
line = item.get("line", "?")
severity = item.get("severity", "?")
desc = item.get("description", "No description")
print(f" Line {line} [{severity}] {desc}")
Run it
Create a file named test_script.py with a few intentional problems.
import os
def fetch_data(user_input):
query = "SELECT * FROM users WHERE name = '" + user_input + "'"
os.system("echo " + user_input)
return query
unused_var = 42
Now run the analyzer.
$ python analyzer.py test_script.py
BUGS (1)
Line 4 [medium] String concatenation into SQL query without parameterization
SECURITY (2)
Line 5 [high] Command injection risk via os.system with unsanitized user input
Line 4 [high] SQL injection vulnerability from raw string concatenation
REFACTORS (1)
Line 8 [low] Unused variable unused_var adds noise and should be removed
Next steps
Feed the JSON output into a CI pipeline so every pull request gets an automatic review comment. Or extend the script to walk an entire directory and aggregate findings into a single SARIF report for GitHub Advanced Security.
Top comments (0)