|
import google.generativeai as genai |
|
import re |
|
import os |
|
import ast |
|
from dotenv import load_dotenv |
|
import sys |
|
import importlib.util |
|
|
|
load_dotenv() |
|
|
|
API_KEY = os.getenv("GOOGLE_API_KEY") |
|
if API_KEY is None: |
|
raise ValueError("⚠️ The API key MY_API_KEY is missing! Check the Secrets in Hugging Face.") |
|
genai.configure(api_key=API_KEY) |
|
model = genai.GenerativeModel("models/gemini-2.0-flash") |
|
|
|
PROMPT = """You are an expert programming assistant. |
|
For the following code, perform the following actions: |
|
- The code must remain exactly the same |
|
- Add clear comments for each important step. |
|
- Rename variables if it makes the code easier to understand. |
|
- Add type annotations if the language supports it. |
|
- For each function, add a Google-style docstring (or equivalent format depending on the language). |
|
|
|
Respond only with the updated code, no explanation. |
|
Here is the code: |
|
|
|
{code} |
|
""" |
|
|
|
def generate_documented_code(input_path: str, output_path: str) -> str: |
|
""" |
|
Generate a documented version of the code from the given input file and save it to the output file. |
|
|
|
Args: |
|
input_path (str): Path to the original code file. |
|
output_path (str): Path where the documented code will be saved. |
|
|
|
Returns: |
|
str: The updated and documented code. |
|
""" |
|
with open(input_path, "r", encoding="utf-8") as f: |
|
original_code = f.read() |
|
|
|
prompt = PROMPT.format(code=original_code) |
|
response = model.generate_content(prompt) |
|
updated_code = response.text.strip() |
|
|
|
|
|
lines = updated_code.splitlines() |
|
if len(lines) > 2: |
|
lines = lines[1:-1] |
|
updated_code = "\n".join(lines) |
|
else: |
|
|
|
updated_code = "" |
|
|
|
with open(output_path, "w", encoding="utf-8") as output_file: |
|
output_file.write(updated_code) |
|
|
|
return updated_code |
|
|
|
|
|
def extract_imports_from_file(file_path): |
|
""" |
|
Extract imported modules from a Python file to generate requirements.txt. |
|
|
|
Args: |
|
file_path (str): Path to the Python file. |
|
|
|
Returns: |
|
set: A set of imported module names. |
|
""" |
|
try: |
|
with open(file_path, "r", encoding="utf-8") as f: |
|
tree = ast.parse(f.read()) |
|
except SyntaxError: |
|
return set() |
|
|
|
imports = set() |
|
for node in ast.walk(tree): |
|
if isinstance(node, ast.Import): |
|
for alias in node.names: |
|
imports.add(alias.name.split('.')[0]) |
|
elif isinstance(node, ast.ImportFrom): |
|
if node.module and not node.module.startswith("."): |
|
imports.add(node.module.split('.')[0]) |
|
return imports |
|
|
|
|
|
def is_std_lib(module_name): |
|
""" |
|
Check if a module is part of the Python standard library. |
|
|
|
Args: |
|
module_name (str): The name of the module. |
|
|
|
Returns: |
|
bool: True if the module is part of the standard library, False otherwise. |
|
""" |
|
if module_name in sys.builtin_module_names: |
|
return True |
|
spec = importlib.util.find_spec(module_name) |
|
return spec is not None and "site-packages" not in (spec.origin or "") |
|
|
|
|
|
def generate_requirements_txt(base_path, output_path): |
|
""" |
|
Generate a requirements.txt file based on external imports found in Python files. |
|
|
|
Args: |
|
base_path (str): Root directory of the codebase. |
|
output_path (str): Path to save the generated requirements.txt file. |
|
""" |
|
all_imports = set() |
|
local_modules = set() |
|
|
|
|
|
for root, _, files in os.walk(base_path): |
|
for file in files: |
|
if file.endswith(".py"): |
|
module_name = os.path.splitext(file)[0] |
|
local_modules.add(module_name) |
|
|
|
|
|
for root, _, files in os.walk(base_path): |
|
for file in files: |
|
if file.endswith(".py"): |
|
file_path = os.path.join(root, file) |
|
all_imports.update(extract_imports_from_file(file_path)) |
|
|
|
|
|
external_imports = sorted([ |
|
imp for imp in all_imports |
|
if imp not in local_modules and not is_std_lib(imp) |
|
]) |
|
|
|
|
|
with open(output_path, "w", encoding="utf-8") as f: |
|
for package in external_imports: |
|
f.write(f"{package}\n") |
|
|