import os
import torch
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
import tensorflow as tf
import gradio as gr
from fpdf import FPDF
import pandas as pd
# Load Features from CSV (curate a subset for demo clarity)
features_df = pd.read_csv("Feature-Description.csv")
key_features = [
"Automatic Code Analysis",
"Context-Aware Documentation",
"Real-Time Updates",
"Dependency Mapping",
"API Documentation",
"Test Suite Generation",
"UML Diagram Generation",
"Bug/Issue Identification",
"Natural Language Explanations",
"Customizable Output Formats",
"Language Agnostic",
"Automated Refreshes",
"Analytics and Insights",
"Automated Code Summaries"
]
features_list = [row for row in features_df.to_dict(orient="records") if row["Feature"] in key_features]
def features_html():
html = "
"
for f in features_list:
html += f"- {f['Feature']}: {f['Description']}
"
html += "
"
return html
model_name = "Salesforce/codet5-base"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
class CodeComplexityScorer(tf.keras.Model):
def __init__(self):
super().__init__()
self.dense1 = tf.keras.layers.Dense(32, activation='relu')
self.dense2 = tf.keras.layers.Dense(1, activation='sigmoid')
def call(self, inputs):
x = self.dense1(inputs)
score = self.dense2(x)
return score
complexity_model = CodeComplexityScorer()
def extract_code_features(code_text):
length = len(code_text)
lines = code_text.count('\n') + 1
words = code_text.split()
avg_word_len = sum(len(w) for w in words) / (len(words) + 1)
features = tf.constant([[length/1000, lines/50, avg_word_len/20]], dtype=tf.float32)
return features
LANG_PROMPTS = {
"Python": "summarize Python code:",
"JavaScript": "summarize JavaScript code:",
"Java": "summarize Java code:",
"Other": "summarize code:",
}
def automatic_code_analysis(code_text):
return f"Code contains {code_text.count(chr(10))+1} lines and {len(code_text)} characters."
def context_aware_documentation(code_text):
return "Generates context-aware, readable documentation (demo placeholder)."
def bug_issue_identification(code_text):
return "No obvious issues detected (demo placeholder)."
def automated_code_summaries(code_text):
return "Provides concise summaries of code modules (demo placeholder)."
feature_functions = {
"Automatic Code Analysis": automatic_code_analysis,
"Context-Aware Documentation": context_aware_documentation,
"Bug/Issue Identification": bug_issue_identification,
"Automated Code Summaries": automated_code_summaries,
}
def generate_documentation(code_text, language, export_format, selected_features):
features = extract_code_features(code_text)
complexity_score = complexity_model(features).numpy()[0][0]
prompt = LANG_PROMPTS.get(language, LANG_PROMPTS["Other"])
input_text = f"{prompt} {code_text.strip()}"
inputs = tokenizer.encode(input_text, return_tensors="pt", max_length=512, truncation=True)
summary_ids = model.generate(inputs, max_length=128, num_beams=5, early_stopping=True)
summary = tokenizer.decode(summary_ids[0], skip_special_tokens=True)
extra_sections = ""
for feature in selected_features:
if feature in feature_functions:
extra_sections += f"\n**{feature}:**\n{feature_functions[feature](code_text)}"
doc_output = f"""### AI-Generated Documentation
{summary}
**Code Complexity Score:** {complexity_score:.2f} (0=low,1=high)
{extra_sections}
"""
if export_format == "Markdown":
return doc_output
elif export_format == "PDF":
pdf_filename = "/tmp/generated_doc.pdf"
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
for line in doc_output.split('\n'):
pdf.cell(0, 10, txt=line, ln=True)
pdf.output(pdf_filename)
return pdf_filename
else:
return doc_output
def process_uploaded_file(uploaded_file, language, export_format, selected_features):
code_bytes = uploaded_file.read()
code_text = code_bytes.decode("utf-8", errors="ignore")
return generate_documentation(code_text, language, export_format, selected_features)
# --- CSS: Use .gradio-container for full-page background image ---
custom_css = """
.gradio-container {
background-image: url('https://media.istockphoto.com/photos/programming-code-abstract-technology-background-of-software-developer-picture-id1201405775?b=1&k=20&m=1201405775&s=170667a&w=0&h=XZ-tUfHvW5IRT30nMm7bAbbWrqkGQ-WT8XSS8Pab-eA=');
background-repeat: no-repeat;
background-position: center center;
background-attachment: fixed;
background-size: cover;
min-height: 100vh;
}
#container {
background: rgba(16, 24, 40, 0.85);
border-radius: 22px;
padding: 2.5rem 3.5rem;
max-width: 900px;
margin: 2rem auto 3rem auto;
box-shadow: 0 12px 48px 0 rgba(60,120,220,0.28), 0 1.5px 12px 0 rgba(0,0,0,0.15);
color: #f4f6fa !important;
backdrop-filter: blur(7px);
border: 2.5px solid rgba(0,255,255,0.10);
}
#animated-header {
font-size: 2.6em !important;
font-weight: 900;
text-align: center;
margin-bottom: 1em;
background: linear-gradient(270deg, #00f2fe, #4facfe, #43e97b, #fa709a, #fee140, #00f2fe);
background-size: 800% 800%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradientShift 12s ease-in-out infinite;
letter-spacing: 2px;
text-shadow: 0 2px 8px rgba(0,255,255,0.18);
}
@keyframes gradientShift {
0%{background-position:0% 50%;}
50%{background-position:100% 50%;}
100%{background-position:0% 50%;}
}
#feature-panel {
background: rgba(34, 49, 63, 0.95);
border-radius: 14px;
padding: 1.2rem 1.8rem;
margin-bottom: 1.5rem;
box-shadow: 0 4px 18px rgba(0,255,255,0.10);
max-height: 200px;
overflow-y: auto;
font-size: 1.13em;
line-height: 1.5em;
color: #f4f6fa !important;
border: 2px solid #00f2fe;
animation: fadeInUp 1.2s ease forwards, neon-glow 2.5s infinite alternate;
}
@keyframes fadeInUp {
from {opacity: 0; transform: translateY(20px);}
to {opacity: 1; transform: translateY(0);}
}
@keyframes neon-glow {
0% { box-shadow: 0 0 8px #00f2fe, 0 0 16px #00f2fe70; border-color: #00f2fe;}
100% { box-shadow: 0 0 16px #43e97b, 0 0 32px #43e97b70; border-color: #43e97b;}
}
#generate-btn {
background: linear-gradient(90deg, #43e97b, #38f9d7, #00f2fe);
color: #192a56 !important;
font-weight: 800;
border-radius: 14px;
padding: 0.9em 2.2em;
font-size: 1.25em;
border: none;
box-shadow: 0 6px 24px 0 rgba(0,255,255,0.22);
transition: all 0.3s cubic-bezier(.4,2,.6,1);
letter-spacing: 1px;
outline: none;
}
#generate-btn:hover {
background: linear-gradient(90deg, #fa709a, #fee140);
color: #192a56 !important;
box-shadow: 0 8px 32px rgba(250,112,154,0.22);
transform: scale(1.06);
cursor: pointer;
}
#credits {
text-align: center;
margin-top: 2.5rem;
font-size: 1.15em;
color: #fee140;
font-weight: 800;
letter-spacing: 0.08em;
animation: fadeIn 2s ease forwards;
text-shadow: 0 2px 8px #fa709a50;
}
@media (max-width: 600px) {
#container {
padding: 1rem 0.5rem;
margin: 1rem;
}
#animated-header {
font-size: 1.4em !important;
}
#feature-panel {
padding: 0.7rem 0.7rem;
font-size: 1em;
}
}
"""
with gr.Blocks(css=custom_css, elem_id="container") as demo:
gr.HTML("")
with gr.Row():
gr.HTML(f"Supported Features (scroll if needed):{features_html()}
")
file_input = gr.File(label="Upload Code File (.py, .js, .java)", file_types=[".py", ".js", ".java"])
code_input = gr.Textbox(label="Or Paste Code Here", lines=8, max_lines=15, placeholder="Paste your code snippet here...")
language_dropdown = gr.Dropdown(label="Select Language", choices=["Python", "JavaScript", "Java", "Other"], value="Python")
export_dropdown = gr.Dropdown(label="Export Format", choices=["Markdown", "PDF"], value="Markdown")
feature_options = gr.CheckboxGroup(
label="Select Features to Include",
choices=[f["Feature"] for f in features_list],
value=["Automatic Code Analysis", "Context-Aware Documentation", "Bug/Issue Identification"],
interactive=True,
container=False,
show_label=True,
)
generate_btn = gr.Button("Generate Documentation", elem_id="generate-btn")
output_box = gr.Textbox(label="Generated Documentation", lines=10, max_lines=20, interactive=False, show_copy_button=True)
pdf_output = gr.File(label="Download PDF", visible=False)
gr.HTML("Credits: Sreelekha Putta
")
def on_generate(file_obj, code_str, language, export_format, selected_features):
if file_obj is not None:
result = process_uploaded_file(file_obj, language, export_format, selected_features)
elif code_str.strip() != "":
result = generate_documentation(code_str, language, export_format, selected_features)
else:
return "Please upload a file or paste code to generate documentation.", None
if export_format == "PDF":
return None, gr.update(value=result, visible=True)
else:
return result, gr.update(visible=False)
generate_btn.click(
on_generate,
inputs=[file_input, code_input, language_dropdown, export_dropdown, feature_options],
outputs=[output_box, pdf_output]
)
demo.launch(share=True)