Skip to content

Commit 7e99be7

Browse files
committed
chore(vendor): vendor FalkorDB code-graph-backend
1 parent d98d49c commit 7e99be7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+8822
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FALKORDB_HOST=<host>
2+
FALKORDB_PORT=<port>
3+
FALKORDB_USERNAME=<username>
4+
FALKORDB_PASSWORD=<password>
5+
OPENAI_API_KEY=<openai_api_key>
6+
GEMINI_API_KEY=<gemini_api_key>
7+
SECRET_TOKEN=<secret_token>
8+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "pip" # See documentation for possible values
4+
directory: "/" # Location of package manifests
5+
schedule:
6+
interval: "daily"
7+
target-branch: "staging"
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# This workflow will install Python dependencies, run tests and lint with a single version of Python
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3+
4+
name: Python application
5+
6+
on:
7+
push:
8+
branches: [ "main" ]
9+
pull_request:
10+
branches: [ "main" ]
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
build:
17+
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
- name: Set up Python 3.10
23+
uses: actions/setup-python@v3
24+
with:
25+
python-version: "3.10"
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install flake8 pytest
30+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
31+
- name: Lint with flake8
32+
run: |
33+
# stop the build if there are Python syntax errors or undefined names
34+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
35+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
36+
# flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
37+
38+
# - name: Test with pytest
39+
# run: |
40+
# pytest
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Release image to DockerHub
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
tags: ["v*.*.*"]
7+
branches:
8+
- main
9+
10+
jobs:
11+
build-and-release:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Set tags
18+
run: |
19+
if ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags') }}; then
20+
echo "TAGS=falkordb/code-graph-backend:latest,falkordb/code-graph-backend:${{ github.ref_name }}" >> $GITHUB_ENV
21+
else
22+
echo "TAGS=falkordb/code-graph-backend:edge" >> $GITHUB_ENV
23+
fi
24+
25+
- name: Login to DockerHub
26+
uses: docker/login-action@v3
27+
with:
28+
username: ${{ secrets.DOCKER_USERNAME }}
29+
password: ${{ secrets.DOCKER_PASSWORD }}
30+
31+
- name: Build image
32+
uses: docker/build-push-action@v5
33+
with:
34+
context: .
35+
file: ./Dockerfile
36+
push: true
37+
tags: ${{ env.TAGS }}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Byte-compiled files
2+
*.pyc
3+
*.pyo
4+
*.pyd
5+
__pycache__/
6+
7+
# Virtual environments
8+
venv/
9+
env/
10+
.virtualenv/
11+
12+
# Distribution/build files
13+
build/
14+
dist/
15+
*.egg-info/
16+
.eggs/
17+
18+
# IDE settings
19+
.vscode/
20+
.idea/
21+
*.swp
22+
23+
# Logs and debugging
24+
*.log
25+
*.trace
26+
27+
# OS-specific files
28+
.DS_Store
29+
Thumbs.db
30+
31+
# Testing and coverage
32+
htmlcov/
33+
*.cover
34+
.coverage
35+
.cache/
36+
pytest_cache/
37+
38+
# Jupyter Notebook checkpoints
39+
.ipynb_checkpoints/
40+
41+
# Custom settings
42+
.env
43+
*.sqlite3
44+
.vercel
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 FalkorDB
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
[![Try Free](https://img.shields.io/badge/Try%20Free-FalkorDB%20Cloud-FF8101?labelColor=FDE900&link=https://app.falkordb.cloud)](https://app.falkordb.cloud)
2+
[![Dockerhub](https://img.shields.io/docker/pulls/falkordb/falkordb?label=Docker)](https://hub.docker.com/r/falkordb/falkordb/)
3+
[![Discord](https://img.shields.io/discord/1146782921294884966?style=flat-square)](https://discord.com/invite/6M4QwDXn2w)
4+
5+
## Getting Started
6+
7+
[Live Demo](https://code-graph.falkordb.com/)
8+
9+
## Running locally
10+
11+
### Run FalkorDB
12+
13+
Free cloud instance: https://app.falkordb.cloud/signup
14+
15+
Or by running locally with docker:
16+
17+
```bash
18+
docker run -p 6379:6379 -p 3000:3000 -it --rm falkordb/falkordb:latest
19+
```
20+
21+
### Config
22+
23+
Create your own `.env` file from the `.env.template` file
24+
25+
Start the server:
26+
```bash
27+
flask --app api/index.py run --debug
28+
```
29+
30+
### Creating a graph
31+
32+
Process a local source folder:
33+
34+
```bash
35+
curl -X POST http://127.0.0.1:5000/analyze_folder -H "Content-Type: application/json" -d '{"path": "<FULL_PATH_TO_FOLDER>", "ignore": [<OPTIONAL_IGNORE_LIST>]}' -H "Authorization: <.ENV_SECRET_TOKEN>"
36+
```
37+
38+
For example:
39+
40+
```bash
41+
curl -X POST http://127.0.0.1:5000/analyze_folder -H "Content-Type: application/json" -d '{"path": "/Users/roilipman/Dev/GraphRAG-SDK", "ignore": ["./.github", "./build"]}' -H "Authorization: OpenSesame"
42+
```
43+
44+
## Working with your graph
45+
46+
Once the source code analysis completes your FalkorDB DB will be populated with
47+
a graph representation of your source code, the graph name should be the same as
48+
the name of the folder you've requested to analyze, for the example above a graph named:
49+
"GraphRAG-SDK".
50+
51+
At the moment only the Python and C languages are supported, we do intend to support additional languages.
52+
53+
At this point you can explore and query your source code using various tools
54+
Here are several options:
55+
56+
1. [Code-Graph UI](https://github.com/FalkorDB/code-graph)
57+
1. FalkorDB [Browser](https://github.com/FalkorDB/falkordb-browser/)
58+
2. One of FalkorDB's [clients](https://docs.falkordb.com/clients.html)
59+
3. Use FalkorDB [GraphRAG-SDK](https://github.com/FalkorDB/GraphRAG-SDK) to connect an LLM for natural language exploration.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from .info import *
2+
from .llm import ask
3+
from .graph import *
4+
from .project import *
5+
from .entities import *
6+
from .git_utils import *
7+
from .code_coverage import *
8+
from .analyzers.source_analyzer import *
9+
from .auto_complete import prefix_search
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .source_analyzer import SourceAnalyzer
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
from pathlib import Path
2+
from typing import Optional
3+
4+
from tree_sitter import Language, Node, Parser, Point
5+
from api.entities.entity import Entity
6+
from api.entities.file import File
7+
from abc import ABC, abstractmethod
8+
from multilspy import SyncLanguageServer
9+
10+
class AbstractAnalyzer(ABC):
11+
def __init__(self, language: Language) -> None:
12+
self.language = language
13+
self.parser = Parser(language)
14+
15+
def find_parent(self, node: Node, parent_types: list) -> Node:
16+
while node and node.type not in parent_types:
17+
node = node.parent
18+
return node
19+
20+
@abstractmethod
21+
def is_dependency(self, file_path: str) -> bool:
22+
"""
23+
Check if the file is a dependency.
24+
25+
Args:
26+
file_path (str): The file path.
27+
28+
Returns:
29+
bool: True if the file is a dependency, False otherwise.
30+
"""
31+
32+
pass
33+
34+
@abstractmethod
35+
def resolve_path(self, file_path: str, path: Path) -> str:
36+
"""
37+
Resolve the path of the file.
38+
39+
Args:
40+
file_path (str): The file path.
41+
path (Path): The path to the folder.
42+
43+
Returns:
44+
str: The resolved path.
45+
"""
46+
47+
pass
48+
49+
def resolve(self, files: dict[Path, File], lsp: SyncLanguageServer, file_path: Path, path: Path, node: Node) -> list[tuple[File, Node]]:
50+
try:
51+
locations = lsp.request_definition(str(file_path), node.start_point.row, node.start_point.column)
52+
return [(files[Path(self.resolve_path(location['absolutePath'], path))], files[Path(self.resolve_path(location['absolutePath'], path))].tree.root_node.descendant_for_point_range(Point(location['range']['start']['line'], location['range']['start']['character']), Point(location['range']['end']['line'], location['range']['end']['character']))) for location in locations if location and Path(self.resolve_path(location['absolutePath'], path)) in files]
53+
except Exception as e:
54+
return []
55+
56+
@abstractmethod
57+
def add_dependencies(self, path: Path, files: list[Path]):
58+
"""
59+
Add dependencies to the files.
60+
61+
Args:
62+
path (Path): The path to the folder.
63+
files (dict[Path, File]): The files.
64+
"""
65+
66+
pass
67+
68+
@abstractmethod
69+
def get_entity_label(self, node: Node) -> str:
70+
"""
71+
Get the entity label from the node.
72+
73+
Args:
74+
node (Node): The node.
75+
76+
Returns:
77+
str: The entity label.
78+
"""
79+
pass
80+
81+
@abstractmethod
82+
def get_entity_name(self, node: Node) -> str:
83+
"""
84+
Get the entity name from the node.
85+
86+
Args:
87+
node (Node): The node.
88+
89+
Returns:
90+
str: The entity name.
91+
"""
92+
pass
93+
94+
@abstractmethod
95+
def get_entity_docstring(self, node: Node) -> Optional[str]:
96+
"""
97+
Get the entity docstring from the node.
98+
99+
Args:
100+
node (Node): The node.
101+
102+
Returns:
103+
Optional[str]: The entity docstring.
104+
"""
105+
pass
106+
107+
@abstractmethod
108+
def get_entity_types(self) -> list[str]:
109+
"""
110+
Get the top level entity types for the language.
111+
112+
Returns:
113+
list[str]: The list of top level entity types.
114+
"""
115+
116+
pass
117+
118+
@abstractmethod
119+
def add_symbols(self, entity: Entity) -> None:
120+
"""
121+
Add symbols to the entity.
122+
123+
Args:
124+
entity (Entity): The entity to add symbols to.
125+
"""
126+
127+
pass
128+
129+
@abstractmethod
130+
def resolve_symbol(self, files: dict[Path, File], lsp: SyncLanguageServer, file_path: Path, path: Path, key: str, symbol: Node) -> Entity:
131+
"""
132+
Resolve a symbol to an entity.
133+
134+
Args:
135+
lsp (SyncLanguageServer): The language server.
136+
path (Path): The path to the file.
137+
key (str): The symbol key.
138+
symbol (Node): The symbol node.
139+
140+
Returns:
141+
Entity: The entity.
142+
"""
143+
144+
pass

0 commit comments

Comments
 (0)