DeepGit-lite / app.py
zamalali
Add DeepGit Lite application and workflow files
9494afe
raw
history blame
7.68 kB
import gradio as gr
import os
import time
import threading
import logging
from src.deepgit_lite import run_deepgit_lite
# ---------------------------
# Global Logging Buffer Setup
# ---------------------------
LOG_BUFFER = []
LOG_BUFFER_LOCK = threading.Lock()
class BufferLogHandler(logging.Handler):
def emit(self, record):
log_entry = self.format(record)
with LOG_BUFFER_LOCK:
LOG_BUFFER.append(log_entry)
root_logger = logging.getLogger()
if not any(isinstance(h, BufferLogHandler) for h in root_logger.handlers):
handler = BufferLogHandler()
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
root_logger.addHandler(handler)
def filter_logs(logs):
filtered = []
last_was_fetching = False
for log in logs:
if "HTTP Request:" in log:
if not last_was_fetching:
filtered.append("Fetching repositories...")
last_was_fetching = True
else:
filtered.append(log)
last_was_fetching = False
return filtered
# ---------------------------
# Title, Favicon & Description
# ---------------------------
favicon_html = """
<head>
<link rel="icon" type="image/x-icon" href="file/assets/deepgit.ico">
<title>DeepGit Lite Research Agent</title>
</head>
"""
title = """
<div style="text-align: center; margin-top: 20px;">
<h1 style="font-size: 36px; display: inline-flex; align-items: center; gap: 16px;">
<img src="https://img.icons8.com/?size=100&id=118557&format=png&color=000000" width="64" />
<span>DeepGit Lite</span>
</h1>
<p style="font-size: 18px; color: #555; margin-top: 10px;">
⚙️ A lightweight GitHub research agent for deep semantic search and ranking.
</p>
</div>
"""
description = """<p align="center">
DeepGit Lite is a streamlined version of DeepGit designed to perform advanced semantic research on GitHub repositories with faster response times. It uses query enhancement, dense retrieval via FAISS, activity analysis, and a final multi-factor ranking (combining semantic similarity, activity, and popularity) to deliver the best results.
</p>"""
consent_text = """
<div style="padding: 10px; text-align: center;">
<p>
By using DeepGit Lite, you consent to temporary processing of your query for semantic search and ranking purposes.
</p>
<p>
⭐ Star us on GitHub if you find this tool useful!<br/>
<a href="https://github.com/zamalali/DeepGit" target="_blank">GitHub</a>
</p>
</div>
"""
footer = """
<div style="text-align: center; margin-top: 40px; font-size: 13px; color: #888;">
Made with <span style="color: crimson;">❤️</span> by <b>Zamal</b>
</div>
"""
# ---------------------------
# HTML Table Renderer for DeepGit Lite
# ---------------------------
def format_percent(value):
try:
return f"{float(value) * 100:.1f}%"
except:
return value
def parse_result_to_html(raw_result: str) -> str:
entries = raw_result.strip().split("Final Rank:")
html = """
<style>
table {
width: 100%;
border-collapse: collapse;
margin: 1em 0;
font-size: 14px;
}
th, td {
padding: 12px 15px;
border: 1px solid #ddd;
text-align: left;
vertical-align: top;
}
th {
background-color: #f4f4f4;
}
tr:hover { background-color: #f9f9f9; }
</style>
<table>
<thead>
<tr>
<th>Rank</th>
<th>Title</th>
<th>Link</th>
<th>Semantic Similarity</th>
<th>Activity Score</th>
<th>Final Score</th>
</tr>
</thead>
<tbody>
"""
for entry in entries[1:]:
lines = entry.strip().split("\n")
data = {}
data["Final Rank"] = lines[0].strip()
for line in lines[1:]:
if ": " in line:
key, val = line.split(": ", 1)
data[key.strip()] = val.strip()
html += f"""
<tr>
<td>{data.get('Final Rank', '')}</td>
<td>{data.get('Title', '')}</td>
<td><a href="{data.get('Link', '#')}" target="_blank">GitHub</a></td>
<td>{format_percent(data.get('Semantic Similarity', ''))}</td>
<td>{float(data.get('Activity Score', 0)):.2f}</td>
<td>{format_percent(data.get('Final Score', ''))}</td>
</tr>
"""
html += "</tbody></table>"
return html
# ---------------------------
# Background Workflow Runner for DeepGit Lite
# ---------------------------
def run_lite_workflow(topic, result_container):
result = run_deepgit_lite(topic)
result_container["raw_result"] = result
def stream_lite_workflow(topic):
with LOG_BUFFER_LOCK:
LOG_BUFFER.clear()
result_container = {}
workflow_thread = threading.Thread(target=run_lite_workflow, args=(topic, result_container))
workflow_thread.start()
last_index = 0
while workflow_thread.is_alive() or (last_index < len(LOG_BUFFER)):
with LOG_BUFFER_LOCK:
new_logs = LOG_BUFFER[last_index:]
last_index = len(LOG_BUFFER)
if new_logs:
filtered_logs = filter_logs(new_logs)
status_msg = filtered_logs[-1]
detail_msg = "<br/>".join(filtered_logs)
yield status_msg, detail_msg
time.sleep(0.5)
workflow_thread.join()
with LOG_BUFFER_LOCK:
final_logs = LOG_BUFFER[:]
filtered_final = filter_logs(final_logs)
raw_result = result_container.get("raw_result", "No results returned.")
html_result = parse_result_to_html(raw_result)
yield "", html_result
# ---------------------------
# App UI Setup for DeepGit Lite
# ---------------------------
with gr.Blocks(
theme="gstaff/sketch",
css="""
#main_container { margin: auto; max-width: 900px; }
footer, footer * { display: none !important; }
"""
) as demo:
gr.HTML(favicon_html)
gr.HTML(title)
gr.HTML(description)
with gr.Column(elem_id="user_consent_container") as consent_block:
gr.HTML(consent_text)
agree_button = gr.Button("I Agree", variant="primary")
with gr.Column(elem_id="main_container", visible=False) as main_block:
research_input = gr.Textbox(
label="Research Topic",
placeholder="Enter your research topic here, e.g., 'Instruction-based fine-tuning for LLaMA 2 using chain-of-thought prompting in Python.'",
lines=3
)
run_button = gr.Button("Run DeepGit Lite", variant="primary")
status_display = gr.Markdown("")
detail_display = gr.HTML("")
output_html = gr.HTML("")
state = gr.State([])
def enable_main():
return gr.update(visible=False), gr.update(visible=True)
agree_button.click(fn=enable_main, inputs=[], outputs=[consent_block, main_block], queue=False)
def lite_runner(topic):
for status, details in stream_lite_workflow(topic):
yield status, details
run_button.click(
fn=lite_runner,
inputs=[research_input],
outputs=[status_display, detail_display],
api_name="deepgit_lite",
show_progress=True
)
research_input.submit(
fn=lite_runner,
inputs=[research_input],
outputs=[status_display, detail_display],
api_name="deepgit_lite_submit",
show_progress=True
)
gr.HTML(footer)
demo.queue(max_size=10).launch()