AI-powered Code Review Assistant Python, AI
👤 Sharing: AI
```python
import ast
import difflib
import openai
import os
class CodeReviewAssistant:
"""
An AI-powered code review assistant that leverages OpenAI's models.
"""
def __init__(self, api_key: str = None, model: str = "gpt-4"):
"""
Initializes the CodeReviewAssistant.
Args:
api_key: Your OpenAI API key. If None, it will attempt to read from the
OPENAI_API_KEY environment variable.
model: The OpenAI model to use. Defaults to "gpt-4".
"""
if api_key is None:
api_key = os.environ.get("OPENAI_API_KEY")
if api_key is None:
raise ValueError(
"OpenAI API key not provided. Please set the OPENAI_API_KEY environment variable or pass it directly to the constructor."
)
openai.api_key = api_key
self.model = model
def review_code(self, code: str, file_path: str = None) -> str:
"""
Reviews the provided code and provides feedback.
Args:
code: The code to review.
file_path: Optional file path for context.
Returns:
A string containing the review feedback.
"""
prompt = self._construct_review_prompt(code, file_path)
try:
response = openai.ChatCompletion.create(
model=self.model,
messages=[
{
"role": "system",
"content": "You are a senior software engineer reviewing code. Provide concise, actionable feedback. Focus on correctness, security, performance, readability, and maintainability. Highlight potential bugs and security vulnerabilities. Suggest improvements where possible. If no improvements are needed, say so.",
},
{"role": "user", "content": prompt},
],
temperature=0.5, # Adjust for creativity vs. accuracy
)
review = response.choices[0].message.content
return review
except Exception as e:
return f"Error during code review: {e}"
def suggest_improvements(self, code: str, file_path: str = None) -> str:
"""
Suggests improvements to the code, generating a potentially modified version.
Args:
code: The code to improve.
file_path: Optional file path for context.
Returns:
A string containing the improved code or suggestions if a complete rewrite isn't possible.
"""
prompt = self._construct_improvement_prompt(code, file_path)
try:
response = openai.ChatCompletion.create(
model=self.model,
messages=[
{
"role": "system",
"content": "You are a senior software engineer rewriting code to improve it. Focus on correctness, security, performance, readability, and maintainability. Implement suggested improvements directly in the code where possible. If a full rewrite isn't feasible due to complexity, provide detailed suggestions instead. Preserve existing functionality.",
},
{"role": "user", "content": prompt},
],
temperature=0.3,
)
improved_code = response.choices[0].message.content
return improved_code
except Exception as e:
return f"Error suggesting improvements: {e}"
def identify_bugs(self, code: str, file_path: str = None) -> str:
"""
Identifies potential bugs in the code.
Args:
code: The code to analyze.
file_path: Optional file path for context.
Returns:
A string describing any identified bugs.
"""
prompt = self._construct_bug_identification_prompt(code, file_path)
try:
response = openai.ChatCompletion.create(
model=self.model,
messages=[
{
"role": "system",
"content": "You are a security expert analyzing code for potential bugs and vulnerabilities. Be thorough and precise. Prioritize security-related issues, but also identify potential logic errors, edge cases, and performance bottlenecks that could lead to bugs.",
},
{"role": "user", "content": prompt},
],
temperature=0.1, # Less variance needed for bug hunting.
)
bugs = response.choices[0].message.content
return bugs
except Exception as e:
return f"Error identifying bugs: {e}"
def generate_unit_tests(self, code: str, file_path: str = None) -> str:
"""
Generates unit tests for the given code.
Args:
code: The code to generate tests for.
file_path: Optional file path for context.
Returns:
A string containing the generated unit tests.
"""
prompt = self._construct_unit_test_generation_prompt(code, file_path)
try:
response = openai.ChatCompletion.create(
model=self.model,
messages=[
{
"role": "system",
"content": "You are a software engineer generating comprehensive unit tests for the given code. Use pytest. Ensure high code coverage. Test all key functionalities, including edge cases and error handling.",
},
{"role": "user", "content": prompt},
],
temperature=0.4, # Generate variations of tests
)
tests = response.choices[0].message.content
return tests
except Exception as e:
return f"Error generating unit tests: {e}"
def _construct_review_prompt(self, code: str, file_path: str = None) -> str:
"""Constructs the prompt for code review."""
prompt = f"Please review the following Python code:\n\n```python\n{code}\n```\n"
if file_path:
prompt += f"File path: {file_path}\n"
return prompt
def _construct_improvement_prompt(self, code: str, file_path: str = None) -> str:
"""Constructs the prompt for code improvement."""
prompt = f"Please improve the following Python code:\n\n```python\n{code}\n```\n"
if file_path:
prompt += f"File path: {file_path}\n"
prompt += "Return the improved code."
return prompt
def _construct_bug_identification_prompt(
self, code: str, file_path: str = None
) -> str:
"""Constructs the prompt for bug identification."""
prompt = f"Please identify any potential bugs or vulnerabilities in the following Python code:\n\n```python\n{code}\n```\n"
if file_path:
prompt += f"File path: {file_path}\n"
return prompt
def _construct_unit_test_generation_prompt(
self, code: str, file_path: str = None
) -> str:
"""Constructs the prompt for unit test generation."""
prompt = f"Please generate unit tests (using pytest) for the following Python code:\n\n```python\n{code}\n```\n"
if file_path:
prompt += f"File path: {file_path}\n"
prompt += "Return the tests as a single, complete python file."
return prompt
def diff_code(self, original_code: str, modified_code: str) -> str:
"""Generates a diff between two versions of code.
Args:
original_code: The original code.
modified_code: The modified code.
Returns:
A string representing the diff.
"""
diff = difflib.unified_diff(
original_code.splitlines(), modified_code.splitlines(), lineterm=""
)
return "\n".join(diff)
if __name__ == "__main__":
# Example Usage (replace with your actual API key and code)
try:
api_key = os.environ["OPENAI_API_KEY"] # Get from environment variables
except KeyError:
print(
"Please set the OPENAI_API_KEY environment variable with your OpenAI API key."
)
exit()
code_to_review = """
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
return a / b
"""
assistant = CodeReviewAssistant(api_key=api_key)
print("Code Review:")
review = assistant.review_code(code_to_review)
print(review)
print("\n")
print("Suggested Improvements:")
improved_code = assistant.suggest_improvements(code_to_review)
print(improved_code)
print("\n")
print("Identified Bugs:")
bugs = assistant.identify_bugs(code_to_review)
print(bugs)
print("\n")
print("Generated Unit Tests:")
unit_tests = assistant.generate_unit_tests(code_to_review)
print(unit_tests)
print("\n")
# Example of showing a diff if improvements were suggested
if improved_code != code_to_review and "Error" not in improved_code:
print("Diff between original and improved code:")
diff = assistant.diff_code(code_to_review, improved_code)
print(diff)
```
👁️ Viewed: 9
Comments