File size: 5,994 Bytes
968d06d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import os
import sys
import io
from dotenv import load_dotenv
import google.generativeai as genai
from openai import OpenAI
import gradio as gr

# Load environment variables
load_dotenv()
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

# Configure APIs
genai.configure(api_key=GEMINI_API_KEY)
openai = OpenAI(api_key=OPENAI_API_KEY)

# Model names
GEMINI_MODEL = "gemini-2.0-flash"  # Gemini model
OPENAI_MODEL = "gpt-4o-mini"  # OpenAI model (you can use "gpt-3.5-turbo" if needed)

def create_system_prompt():
    """Create the system prompt for the model."""
    system_message = "You are an assistant that adds high-quality docstrings and comments to Python code. "
    system_message += "Your task is to analyze the code and add appropriate documentation following PEP 257 conventions. "
    system_message += "Add function/class/module docstrings and inline comments where helpful. "
    system_message += "Don't change the functionality of the code, only add documentation. "
    system_message += "Use descriptive docstrings that explain parameters, return values, and exceptions raised."
    return system_message

def create_user_prompt(code):
    """Create the user prompt with the code to be documented."""
    user_prompt = "Please add appropriate docstrings and comments to the following Python code. "
    user_prompt += "Follow PEP 257 style for docstrings. Add comments only where they add value. "
    user_prompt += "Don't change the functionality of the code.\n\n"
    user_prompt += code
    return user_prompt

def document_code_with_gemini(code):
    """Generate documentation for the provided code using Gemini."""
    system_prompt = create_system_prompt()
    user_prompt = create_user_prompt(code)
    
    # Use Gemini to generate documentation
    model = genai.GenerativeModel(GEMINI_MODEL)
    response = model.generate_content(
        f"{system_prompt}\n\n{user_prompt}",
        generation_config=genai.GenerationConfig(
            temperature=0.7,
            max_output_tokens=2048,
        ),
    )
    
    # Clean up the response
    documented_code = response.text.replace("```python", "").replace("```", "").strip()
    return documented_code

def document_code_with_openai(code):
    """Generate documentation for the provided code using OpenAI."""
    system_prompt = create_system_prompt()
    user_prompt = create_user_prompt(code)
    
    # Use OpenAI to generate documentation
    response = openai.chat.completions.create(
        model=OPENAI_MODEL,
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt},
        ],
        temperature=0.7,
        max_tokens=2048,
    )
    
    # Clean up the response
    documented_code = response.choices[0].message.content.replace("```python", "").replace("```", "").replace("python", "")
    return documented_code

def document_code(code, api_choice):
    """Generate documentation using the selected API."""
    if api_choice == "Gemini":
        return document_code_with_gemini(code)
    elif api_choice == "OpenAI":
        return document_code_with_openai(code)
    else:
        return "Invalid API choice."

def execute_python(code):
    """Execute Python code and return the output."""
    try:
        output = io.StringIO()
        sys.stdout = output
        exec(code)
        return output.getvalue()
    except Exception as e:
        return f"Error: {str(e)}"
    finally:
        sys.stdout = sys.__stdout__

def create_interface():
    """Create the Gradio interface for the documentation tool."""
    sample_code = """
def fibonacci(n):
    fib_series = []
    a, b = 0, 1
    for _ in range(n):
        fib_series.append(a)
        a, b = b, a + b
    return fib_series

n = 10  
fib_series = fibonacci(n)
print("Fibonacci series up to", n, "terms:", fib_series)
"""

    css = """
    .original {background-color: #2d2d2d; color: #f8f8f2;}
    .documented {background-color: #1e1e1e; color: #f8f8f2;}

    /* Custom button styles */
    #add-documentation-btn {background-color: #007bff; color: white; font-weight: bold;} /* Blue for Add Documentation */
    #run-original-btn {background-color: #28a745; color: white; font-weight: bold;} /* Green for Run Original Code */
    #run-documented-btn {background-color: #6f42c1; color: white; font-weight: bold;} /* Purple for Run Documented Code */

    /* Ensure all buttons have white bold text */
    button {color: white; font-weight: bold;}
    """

    with gr.Blocks(css=css) as ui:
        gr.Markdown("## Automatic Python Documentation Generator")
        
        with gr.Row():
            input_code = gr.Textbox(label="Original Python code:", value=sample_code, lines=15, elem_classes=["original"])
            documented_code = gr.Textbox(label="Documented Python code:", lines=15, elem_classes=["documented"])
        
        with gr.Row():
            api_choice = gr.Radio(["Gemini", "OpenAI"], label="Select API", value="Gemini")
            document_btn = gr.Button("Add Documentation", elem_id="add-documentation-btn")
        
        with gr.Row():
            run_original = gr.Button("Run Original Code", elem_id="run-original-btn")
            run_documented = gr.Button("Run Documented Code", elem_id="run-documented-btn")
        
        with gr.Row():
            original_output = gr.TextArea(label="Original code output:")
            documented_output = gr.TextArea(label="Documented code output:")
        
        document_btn.click(document_code, inputs=[input_code, api_choice], outputs=[documented_code])
        run_original.click(execute_python, inputs=[input_code], outputs=[original_output])
        run_documented.click(execute_python, inputs=[documented_code], outputs=[documented_output])
        
    return ui

def main():
    """Main function to launch the interface."""
    ui = create_interface()
    ui.launch(inbrowser=True)

if __name__ == "__main__":
    main()