CoolFace
Apppublic

mkhekare/Lineage

sourceHugging Faceapache-2.0updated 1y agoView on Hugging Face
0likes
app.py334 linesDownload Raw Back to root
1import gradio as gr2import networkx as nx3import ast4import os5import tempfile6from pathlib import Path7import shutil8import uuid9import spacy10from pyvis.network import Network11from git import Repo12from huggingface_hub import InferenceClient13import re14 15# Initialize NLP and AI16nlp = spacy.load("en_core_web_sm")17HF_TOKEN = os.getenv("HF_TOKEN")18 19class CodeAnalyzer:20    def __init__(self):21        self.graph = nx.DiGraph()22        self.entity_map = {}23        self.code_context = ""24        self.current_file = ""25        self.imports = []26 27    def parse_code(self, code: str, language: str = "python", file_path: str = ""):28        self.current_file = file_path if file_path else "input.py"29        self.code_context = code30        self.graph = nx.DiGraph()31        self.entity_map = {}32        self.imports = []33        34        if language == "python":35            return self._parse_python(code)36        else:37            raise ValueError(f"Unsupported language: {language}")38 39    def _parse_python(self, code: str):40        try:41            tree = ast.parse(code)42            self._analyze_ast(tree)43            self._analyze_comments(code)44            self._analyze_import_statements(code)45            self._infer_relationships()46            return self._generate_visualization(), self._generate_report()47        except SyntaxError as e:48            raise ValueError(f"Syntax error in code: {str(e)}")49        except Exception as e:50            raise ValueError(f"Error parsing code: {str(e)}")51 52    # [All analysis methods remain the same as previous version]53 54    def _generate_visualization(self):55        """Generate interactive visualization with error handling"""56        try:57            if len(self.graph.nodes) == 0:58                raise ValueError("No entities found to visualize")59                60            net = Network(61                height="750px",62                width="100%",63                bgcolor="#f9f9f9",64                font_color="#333",65                directed=True,66                notebook=False67            )68            69            # [Rest of visualization code remains the same]70            71            return html72        except Exception as e:73            return f"<div class='error'>Visualization Error: {str(e)}</div>"74 75    def _generate_report(self):76        """Generate report with error handling"""77        try:78            if len(self.graph.nodes) == 0:79                raise ValueError("No code entities found to report")80                81            # [Rest of report generation code remains the same]82            83            return report84        except Exception as e:85            return f"# Report Generation Error\n\n{str(e)}"86 87def analyze_local_code(code: str):88    """Analyze local code with proper error handling"""89    analyzer = CodeAnalyzer()90    try:91        if not code.strip():92            raise ValueError("No code provided")93        return analyzer.parse_code(code)94    except Exception as e:95        return f"<div class='error'>Analysis Error: {str(e)}</div>", f"# Error\n\n{str(e)}"96 97def analyze_github_repo(repo_url: str):98    """Analyze GitHub repository with robust error handling"""99    try:100        if not repo_url.strip():101            raise ValueError("No repository URL provided")102            103        # Clean and validate URL104        if 'github.com' not in repo_url:105            raise ValueError("Invalid GitHub URL - must contain 'github.com'")106            107        if '/blob/' in repo_url:108            # Convert blob URL to raw repository URL109            parts = repo_url.split('/blob/')110            repo_url = f"{parts[0]}.git"111        elif not repo_url.endswith('.git'):112            repo_url = f"{repo_url.rstrip('/')}.git"113        114        # Clone repository115        repo_name = repo_url.split('/')[-1].replace('.git', '')116        repo_dir = Path(tempfile.gettempdir()) / repo_name117        118        if repo_dir.exists():119            shutil.rmtree(repo_dir)120        121        print(f"Cloning repository: {repo_url}")  # Debug log122        Repo.clone_from(repo_url, repo_dir)123        124        # Analyze Python files125        analyzer = CodeAnalyzer()126        master_graph = nx.DiGraph()127        analyzed_files = 0128        129        for py_file in repo_dir.glob('**/*.py'):130            try:131                with open(py_file, 'r', encoding='utf-8') as f:132                    code = f.read()133                    graph, _ = analyzer.parse_code(code, file_path=str(py_file))134                    master_graph = nx.compose(master_graph, graph)135                    analyzed_files += 1136            except Exception as e:137                print(f"Skipping {py_file}: {str(e)}")138                continue139        140        if analyzed_files == 0:141            raise ValueError("No valid Python files found in repository")142        143        analyzer.graph = master_graph144        analyzer.current_file = f"GitHub Repository: {repo_name}"145        return analyzer._generate_visualization(), analyzer._generate_report()146        147    except Exception as e:148        error_msg = f"Repository Analysis Failed: {str(e)}"149        print(error_msg)  # Debug log150        return f"<div class='error'>{error_msg}</div>", f"# Error\n\n{error_msg}"151 152def query_deepseek(prompt: str, code_context: str = ""):153    """Query DeepSeek AI with proper error handling"""154    try:155        if not prompt.strip():156            return "Please enter a question"157            158        if not HF_TOKEN:159            return "AI features disabled - missing API key"160        161        client = InferenceClient(162            provider="together",163            api_key=HF_TOKEN164        )165        166        messages = [{167            "role": "user",168            "content": f"""Analyze this Python code and answer the question:169            170            {code_context[:2000]}171            172            Question: {prompt}173            174            Provide detailed technical analysis focusing on:175            - Data flow and dependencies176            - Potential issues177            - Optimization suggestions178            """179        }]180        181        response = client.chat.completions.create(182            model="deepseek-ai/DeepSeek-R1",183            messages=messages,184            max_tokens=500185        )186        187        if not response.choices:188            return "No response generated from AI"189            190        output = response.choices[0].message.content191        return re.sub(r"<think>.*?</think>", "", output, flags=re.DOTALL).strip()192        193    except Exception as e:194        return f"AI Error: {str(e)}"195 196# Gradio Interface with improved UI197with gr.Blocks(198    title="Code Lineage Analyzer",199    css="""200    .gradio-container {max-width: 1200px !important; margin: 0 auto;}201    .error {color: #ff4d4d; padding: 10px; background: #fff0f0; border-radius: 5px; margin: 10px 0;}202    .graph-container {border: 1px solid #e0e0e0; border-radius: 8px; padding: 15px; background: white; box-shadow: 0 2px 4px rgba(0,0,0,0.05); min-height: 800px;}203    .tab {padding: 20px; background: #f9f9f9; border-radius: 8px; margin-top: 10px;}204    .header {background: linear-gradient(135deg, #6e8efb, #a777e3); padding: 20px; color: white; border-radius: 8px 8px 0 0; margin-bottom: 20px;}205    .input-section {background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); margin-bottom: 20px;}206    .btn-primary {background: linear-gradient(135deg, #6e8efb, #a777e3) !important; border: none !important; color: white !important;}207    .btn-primary:hover {background: linear-gradient(135deg, #5d7de9, #9666d6) !important;}208    .loading {color: #666; font-style: italic;}209    """210) as demo:211    with gr.Column():212        # Header213        gr.Markdown("""214        <div class="header">215        <h1 style="margin: 0;">๐Ÿƒ Advanced Code Lineage Analyzer</h1>216        <p style="margin: 0; opacity: 0.9;">Visualize code dependencies, analyze repositories, and get AI-powered insights</p>217        </div>218        """)219        220        # Main Tabs221        with gr.Tabs():222            # Code Analysis Tab223            with gr.Tab("Code Analysis"):224                with gr.Row():225                    with gr.Column(scale=1, min_width=400):226                        with gr.Group(elem_classes="input-section"):227                            code_input = gr.Code(228                                label="Python Code",229                                language="python",230                                lines=20,231                                value="""class Person:232    def __init__(self, name):233        self.name = name234        self.parents = []235        self.children = []236 237    def add_parent(self, parent):238        self.parents.append(parent)239        parent.children.append(self)240 241    def get_lineage(self, generation=0):242        lineage = " " * generation + self.name + "\\n"243        for child in self.children:244            lineage += child.get_lineage(generation + 1)245        return lineage246 247# Example usage248alice = Person("Alice")249bob = Person("Bob")250charlie = Person("Charlie")251alice.add_parent(bob)252charlie.add_parent(alice)"""253                            )254                            analyze_btn = gr.Button("Analyze Code", variant="primary", elem_classes="btn-primary")255                    256                    with gr.Column(scale=1, min_width=600):257                        with gr.Tabs():258                            with gr.Tab("Visualization"):259                                graph_output = gr.HTML(elem_classes="graph-container", value="<div style='padding:20px;text-align:center;color:#666;'>Visualization will appear here</div>")260                            with gr.Tab("Report"):261                                report_output = gr.Markdown(value="# Report\n\nAnalysis report will appear here")262                263                analyze_btn.click(264                    analyze_local_code,265                    inputs=[code_input],266                    outputs=[graph_output, report_output],267                    api_name="analyze_code"268                )269            270            # GitHub Analysis Tab271            with gr.Tab("GitHub Analysis"):272                with gr.Row():273                    with gr.Column(scale=1, min_width=400):274                        with gr.Group(elem_classes="input-section"):275                            repo_input = gr.Textbox(276                                label="GitHub Repository URL",277                                placeholder="https://github.com/user/repo"278                            )279                            gr.Examples(280                                examples=[281                                    "https://github.com/psf/requests",282                                    "https://github.com/django/django"283                                ],284                                inputs=[repo_input],285                                label="Try these repositories:"286                            )287                            repo_btn = gr.Button("Analyze Repository", variant="primary", elem_classes="btn-primary")288                    289                    with gr.Column(scale=1, min_width=600):290                        with gr.Tabs():291                            with gr.Tab("Visualization"):292                                repo_graph = gr.HTML(elem_classes="graph-container", value="<div style='padding:20px;text-align:center;color:#666;'>Repository visualization will appear here</div>")293                            with gr.Tab("Report"):294                                repo_report = gr.Markdown(value="# Repository Report\n\nAnalysis report will appear here")295                296                repo_btn.click(297                    analyze_github_repo,298                    inputs=[repo_input],299                    outputs=[repo_graph, repo_report],300                    api_name="analyze_repo"301                )302            303            # AI Assistant Tab304            with gr.Tab("AI Assistant"):305                with gr.Row():306                    with gr.Column(scale=1, min_width=400):307                        with gr.Group(elem_classes="input-section"):308                            ai_prompt = gr.Textbox(309                                label="Ask about the code",310                                placeholder="Explain the data flow in this code..."311                            )312                            ai_context = gr.Code(313                                label="Code Context (optional)",314                                language="python",315                                lines=10,316                                interactive=True317                            )318                            ai_btn = gr.Button("Get AI Analysis", variant="primary", elem_classes="btn-primary")319                    320                    with gr.Column(scale=1, min_width=600):321                        ai_output = gr.Markdown(322                            label="AI Analysis",323                            value="### AI Insights\n\nAI-powered analysis will appear here"324                        )325                326                ai_btn.click(327                    query_deepseek,328                    inputs=[ai_prompt, ai_context],329                    outputs=[ai_output],330                    api_name="query_ai"331                )332 333if __name__ == "__main__":334    demo.launch()