Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,11 @@ CYPHER_ENDPOINT=http://localhost:11434/v1
MEMGRAPH_HOST=localhost
MEMGRAPH_PORT=7687
MEMGRAPH_HTTP_PORT=7444
# Memgraph authentication credentials
# Leave MEMGRAPH_USERNAME empty (or omit it) if your Memgraph instance doesn't require authentication
# If authentication is enabled, provide both username and password
# Common defaults: username=neo4j, password=password (or your custom credentials)
MEMGRAPH_USERNAME=
MEMGRAPH_PASSWORD=
LAB_PORT=3000
TARGET_REPO_PATH=.
2 changes: 2 additions & 0 deletions codebase_rag/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class AppConfig(BaseSettings):
MEMGRAPH_HOST: str = "localhost"
MEMGRAPH_PORT: int = 7687
MEMGRAPH_HTTP_PORT: int = 7444
MEMGRAPH_USERNAME: str | None = None
MEMGRAPH_PASSWORD: str | None = None
LAB_PORT: int = 3000
MEMGRAPH_BATCH_SIZE: int = 1000

Expand Down
8 changes: 8 additions & 0 deletions codebase_rag/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,8 @@ async def main_async(repo_path: str, batch_size: int) -> None:
host=settings.MEMGRAPH_HOST,
port=settings.MEMGRAPH_PORT,
batch_size=batch_size,
username=settings.MEMGRAPH_USERNAME,
password=settings.MEMGRAPH_PASSWORD,
) as ingestor:
console.print("[bold green]Successfully connected to Memgraph.[/bold green]")
console.print(
Expand Down Expand Up @@ -870,6 +872,8 @@ def start(
host=settings.MEMGRAPH_HOST,
port=settings.MEMGRAPH_PORT,
batch_size=effective_batch_size,
username=settings.MEMGRAPH_USERNAME,
password=settings.MEMGRAPH_PASSWORD,
) as ingestor:
if clean:
console.print("[bold yellow]Cleaning database...[/bold yellow]")
Expand Down Expand Up @@ -930,6 +934,8 @@ def export(
host=settings.MEMGRAPH_HOST,
port=settings.MEMGRAPH_PORT,
batch_size=effective_batch_size,
username=settings.MEMGRAPH_USERNAME,
password=settings.MEMGRAPH_PASSWORD,
) as ingestor:
console.print("[bold cyan]Exporting graph data...[/bold cyan]")
if not _export_graph_to_file(ingestor, output):
Expand Down Expand Up @@ -970,6 +976,8 @@ async def main_optimize_async(
host=settings.MEMGRAPH_HOST,
port=settings.MEMGRAPH_PORT,
batch_size=effective_batch_size,
username=settings.MEMGRAPH_USERNAME,
password=settings.MEMGRAPH_PASSWORD,
) as ingestor:
console.print("[bold green]Successfully connected to Memgraph.[/bold green]")

Expand Down
2 changes: 2 additions & 0 deletions codebase_rag/mcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ def create_server() -> tuple[Server, MemgraphIngestor]:
host=settings.MEMGRAPH_HOST,
port=settings.MEMGRAPH_PORT,
batch_size=settings.MEMGRAPH_BATCH_SIZE,
username=settings.MEMGRAPH_USERNAME,
password=settings.MEMGRAPH_PASSWORD,
)

# CypherGenerator gets config from settings automatically
Expand Down
31 changes: 29 additions & 2 deletions codebase_rag/services/graph_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,24 @@
class MemgraphIngestor:
"""Handles all communication and query execution with the Memgraph database."""

def __init__(self, host: str, port: int, batch_size: int = 1000):
def __init__(
self,
host: str,
port: int,
batch_size: int = 1000,
username: str | None = None,
password: str | None = None,
):
self._host = host
self._port = port
self._username = username
self._password = password
# Validate authentication: both username and password must be provided together
if (self._username is None) != (self._password is None):
raise ValueError(
"Both username and password are required for authentication. "
"Either provide both or neither."
)
if batch_size < 1:
raise ValueError("batch_size must be a positive integer")
self.batch_size = batch_size
Expand All @@ -32,7 +47,19 @@ def __init__(self, host: str, port: int, batch_size: int = 1000):

def __enter__(self) -> "MemgraphIngestor":
logger.info(f"Connecting to Memgraph at {self._host}:{self._port}...")
self.conn = mgclient.connect(host=self._host, port=self._port)
# Build connection parameters - only include username/password if provided
connect_params = {
"host": self._host,
"port": self._port,
}

# Only add authentication parameters if both username and password are provided
# This allows connection to Memgraph instances without authentication
if self._username is not None:
connect_params["username"] = self._username
connect_params["password"] = self._password

self.conn = mgclient.connect(**connect_params)
self.conn.autocommit = True
logger.info("Successfully connected to Memgraph.")
return self
Expand Down
2 changes: 2 additions & 0 deletions realtime_updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ def start_watcher(
host=host,
port=port,
batch_size=effective_batch_size,
username=settings.MEMGRAPH_USERNAME,
password=settings.MEMGRAPH_PASSWORD,
) as ingestor:
updater = GraphUpdater(ingestor, repo_path_obj, parsers, queries)

Expand Down