Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,44 @@
# Byte-compiled files
*.pyc
*.pyo
*.pyd
__pycache__/

# Virtual environments
venv/
env/
.virtualenv/

# Distribution/build files
build/
dist/
*.egg-info/
.eggs/

# IDE settings
.vscode/
.idea/
*.swp

# Logs and debugging
*.log
*.trace

# OS-specific files
.DS_Store
Thumbs.db

# Testing and coverage
htmlcov/
*.cover
.coverage
.cache/
pytest_cache/

# Jupyter Notebook checkpoints
.ipynb_checkpoints/

# Custom settings
.env
*.sqlite3
.vercel
Binary file removed api/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file removed api/__pycache__/app.cpython-312.pyc
Binary file not shown.
Binary file removed api/__pycache__/auto_complete.cpython-312.pyc
Binary file not shown.
Binary file removed api/__pycache__/graph.cpython-312.pyc
Binary file not shown.
Binary file removed api/__pycache__/info.cpython-312.pyc
Binary file not shown.
Binary file removed api/__pycache__/llm.cpython-312.pyc
Binary file not shown.
Binary file removed api/__pycache__/project.cpython-312.pyc
Binary file not shown.
Binary file removed api/analyzers/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file removed api/analyzers/__pycache__/analyzer.cpython-312.pyc
Binary file not shown.
Binary file not shown.
Binary file removed api/analyzers/__pycache__/utils.cpython-312.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
6 changes: 4 additions & 2 deletions api/analyzers/source_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def analyze_sources(self, ignore: List[str]) -> None:
# Second pass analysis of the source code
self.second_pass(ignore, executor)

def analyze(self, path: str, g: Graph, ignore: Optional[List[str]] = []) -> None:
def analyze_local_folder(self, path: str, g: Graph, ignore: Optional[List[str]] = []) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix mutable default argument

Using mutable default arguments in Python can lead to unexpected behavior. The empty list [] as a default argument is shared across function calls.

Replace with:

-    def analyze_local_folder(self, path: str, g: Graph, ignore: Optional[List[str]] = []) -> None:
+    def analyze_local_folder(self, path: str, g: Graph, ignore: Optional[List[str]] = None) -> None:

And add at the beginning of the method:

        if ignore is None:
            ignore = []
🧰 Tools
🪛 Ruff (0.8.0)

138-138: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

"""
Analyze path.

Expand All @@ -144,6 +144,8 @@ def analyze(self, path: str, g: Graph, ignore: Optional[List[str]] = []) -> None
ignore (List(str)): List of paths to skip
"""

logging.info(f"Analyzing local folder {path}")

# Save original working directory for later restore
original_dir = Path.cwd()

Expand Down Expand Up @@ -179,4 +181,4 @@ def analyze_local_repository(self, path: str, ignore: Optional[List[str]] = [])
self.graph.set_graph_commit(head.hexsha)

return self.graph

Binary file removed api/code_coverage/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed api/entities/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file removed api/entities/__pycache__/argument.cpython-312.pyc
Binary file not shown.
Binary file removed api/entities/__pycache__/cls.cpython-312.pyc
Binary file not shown.
Binary file not shown.
Binary file removed api/entities/__pycache__/file.cpython-312.pyc
Binary file not shown.
Binary file removed api/entities/__pycache__/function.cpython-312.pyc
Binary file not shown.
Binary file removed api/entities/__pycache__/struct.cpython-312.pyc
Binary file not shown.
41 changes: 41 additions & 0 deletions api/index.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import datetime
from api import *
from pathlib import Path
Comment on lines 3 to +4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Replace star import with explicit imports

Star imports (from api import *) make it unclear which symbols are being imported and can lead to naming conflicts.

Replace with explicit imports:

-from api import *
+from api.analyzers.source_analyzer import SourceAnalyzer
+from api.graph import Graph
+from api.utils import graph_exists, get_repos, get_repo_info, ask

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.0)

3-3: from api import * used; unable to detect undefined names

(F403)

from typing import Optional
from functools import wraps
from falkordb import FalkorDB
Expand Down Expand Up @@ -309,3 +310,43 @@ def chat():
response = { 'status': 'success', 'response': answer }

return jsonify(response), 200

@app.route('/analyze_folder', methods=['POST'])
@token_required # Apply token authentication decorator
def analyze_folder():
"""
Endpoint to analyze local source code
Expects 'path' and optionaly an ignore list.

Returns:
Status code
"""

# Get JSON data from the request
data = request.get_json()

# Get query parameters
path = data.get('path')
ignore = data.get('ignore', [])

# Validate 'path' parameter
if not path:
logging.error("'path' is missing from the request.")
return jsonify({"status": "'path' is required."}), 400

proj_name = Path(path).name

Comment on lines +351 to +352
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation for project name

The project name is derived from the path without validation, which could lead to issues with special characters or empty names.

Add validation:

-    proj_name = Path(path).name
+    proj_name = Path(path).name
+    if not proj_name or proj_name.startswith('.'):
+        logging.error(f"Invalid project name derived from path: {proj_name}")
+        return jsonify({"status": "Invalid path: cannot derive valid project name"}), 400
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
proj_name = Path(path).name
proj_name = Path(path).name
if not proj_name or proj_name.startswith('.'):
logging.error(f"Invalid project name derived from path: {proj_name}")
return jsonify({"status": "Invalid path: cannot derive valid project name"}), 400

# Initialize the graph with the provided project name
g = Graph(proj_name)

# Analyze source code within given folder
analyzer = SourceAnalyzer()
analyzer.analyze_local_folder(path, g, ignore)

# Return response
response = {
'status': 'success'
}

return jsonify(response), 200
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Enhance error handling and input validation

The current implementation lacks comprehensive error handling for file system operations and input validation.

Consider the following improvements:

 @app.route('/analyze_folder', methods=['POST'])
 @token_required
 def analyze_folder():
     """
     Endpoint to analyze local source code
-    Expects 'path' and optionaly an ignore list.
+    Expects 'path' and optionally an ignore list.
 
     Returns:
-        Status code
+        JSON response with status and error message if applicable
+        Status codes:
+            200: Success
+            400: Invalid input
+            500: Internal server error
     """
     # Get JSON data from the request
     data = request.get_json()
 
     # Get query parameters
     path      = data.get('path')
     ignore    = data.get('ignore', [])
 
-    # Validate 'path' parameter
+    # Validate input parameters
     if not path:
         logging.error("'path' is missing from the request.")
         return jsonify({"status": "'path' is required."}), 400
 
+    # Validate path exists and is a directory
+    if not os.path.isdir(path):
+        logging.error(f"Path '{path}' does not exist or is not a directory")
+        return jsonify({"status": "Invalid path: must be an existing directory"}), 400
+
+    # Validate ignore list contains valid paths
+    if not isinstance(ignore, list):
+        logging.error("'ignore' must be a list of paths")
+        return jsonify({"status": "'ignore' must be a list of paths"}), 400
+
     proj_name = Path(path).name
 
-    # Initialize the graph with the provided project name
-    g = Graph(proj_name)
+    try:
+        # Initialize the graph with the provided project name
+        g = Graph(proj_name)
 
-    # Analyze source code within given folder
-    analyzer = SourceAnalyzer()
-    analyzer.analyze_local_folder(path, g, ignore)
+        # Analyze source code within given folder
+        analyzer = SourceAnalyzer()
+        analyzer.analyze_local_folder(path, g, ignore)
 
-    # Return response
-    response = {
-        'status': 'success'
-    }
+        # Return response
+        response = {
+            'status': 'success',
+            'project': proj_name
+        }
+        return jsonify(response), 200
 
-    return jsonify(response), 200
+    except Exception as e:
+        logging.error(f"Error analyzing folder {path}: {e}")
+        return jsonify({
+            'status': 'error',
+            'message': str(e)
+        }), 500
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@app.route('/analyze_folder', methods=['POST'])
@token_required # Apply token authentication decorator
def analyze_folder():
"""
Endpoint to analyze local source code
Expects 'path' and optionaly an ignore list.
Returns:
Status code
"""
# Get JSON data from the request
data = request.get_json()
# Get query parameters
path = data.get('path')
ignore = data.get('ignore', [])
# Validate 'path' parameter
if not path:
logging.error("'path' is missing from the request.")
return jsonify({"status": "'path' is required."}), 400
proj_name = Path(path).name
# Initialize the graph with the provided project name
g = Graph(proj_name)
# Analyze source code within given folder
analyzer = SourceAnalyzer()
analyzer.analyze_local_folder(path, g, ignore)
# Return response
response = {
'status': 'success'
}
return jsonify(response), 200
@app.route('/analyze_folder', methods=['POST'])
@token_required
def analyze_folder():
"""
Endpoint to analyze local source code
Expects 'path' and optionally an ignore list.
Returns:
JSON response with status and error message if applicable
Status codes:
200: Success
400: Invalid input
500: Internal server error
"""
# Get JSON data from the request
data = request.get_json()
# Get query parameters
path = data.get('path')
ignore = data.get('ignore', [])
# Validate input parameters
if not path:
logging.error("'path' is missing from the request.")
return jsonify({"status": "'path' is required."}), 400
# Validate path exists and is a directory
if not os.path.isdir(path):
logging.error(f"Path '{path}' does not exist or is not a directory")
return jsonify({"status": "Invalid path: must be an existing directory"}), 400
# Validate ignore list contains valid paths
if not isinstance(ignore, list):
logging.error("'ignore' must be a list of paths")
return jsonify({"status": "'ignore' must be a list of paths"}), 400
proj_name = Path(path).name
try:
# Initialize the graph with the provided project name
g = Graph(proj_name)
# Analyze source code within given folder
analyzer = SourceAnalyzer()
analyzer.analyze_local_folder(path, g, ignore)
# Return response
response = {
'status': 'success',
'project': proj_name
}
return jsonify(response), 200
except Exception as e:
logging.error(f"Error analyzing folder {path}: {e}")
return jsonify({
'status': 'error',
'message': str(e)
}), 500
🧰 Tools
🪛 Ruff (0.8.0)

340-340: Graph may be undefined, or defined from star imports

(F405)


343-343: SourceAnalyzer may be undefined, or defined from star imports

(F405)


Loading