Skip to content

Staging-->Main#612

Open
gkorland wants to merge 23 commits intomainfrom
staging
Open

Staging-->Main#612
gkorland wants to merge 23 commits intomainfrom
staging

Conversation

@gkorland
Copy link
Contributor

Staging-->Main

gkorland and others added 10 commits March 12, 2026 13:52
Remove @public_access decorator from analyze_repo and switch_commit
endpoints so that all three mutating endpoints (analyze_folder,
analyze_repo, switch_commit) require a valid token even when
CODE_GRAPH_PUBLIC=1. Read-only endpoints remain publicly accessible.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace Flask with FastAPI + Uvicorn in pyproject.toml
- Rewrite api/index.py: Pydantic request models, Depends() auth,
  FileResponse SPA serving, JSONResponse error responses
- Auth decorators become dependency injection:
  public_or_auth (public endpoints), token_required (mutating endpoints)
- Rewrite tests/index.py: FastAPI app factory, explicit imports
- Update 7 endpoint test files: TestClient, .json() method, /api/ URL prefix
- Update Makefile, start.sh, CI workflow: flask run -> uvicorn api.index:app
- Endpoints remain synchronous (FastAPI auto-threads blocking calls)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- serve_spa: resolve path and verify it stays within STATIC_DIR
- chat endpoint: log exception server-side, return generic error to client
- Apply same fixes to test app

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Match production auth by using token_required (not public_access)
for analyze_repo and switch_commit in the test app.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…gging

- serve_spa: replace str().startswith() with Path.is_relative_to() to prevent
  prefix-collision path traversal (e.g. dist_evil matching dist)
- analyze_folder: add ALLOWED_ANALYSIS_DIR containment check to prevent
  traversal outside allowed base directory
- Upgrade logging.error to logging.exception in graph_entities and chat
  handlers for full traceback capture
- Remove unused public_access function from tests/index.py
- Mirror analyze_folder path validation in test app
- Add auth tests for repo_info (public_or_auth) and list_repos endpoints
- Tighten test_find_paths 422 assertions to verify field-specific validation
- Parse response.json() once per response in test_list_commits

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use 'import api.index' consistently instead of mixing with 'from api.index import'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- test_list_repos_with_auth: monkeypatch get_repos for deterministic result,
  assert 200 status and exact payload instead of just != 401
- test_repo_info.py: remove trailing whitespace on status assignments
- test_list_repos.py: remove trailing whitespace on status assignment

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Migrate backend from Flask to FastAPI
Convert all 12 endpoints to async def using native async drivers
(falkordb.asyncio, redis.asyncio) for read endpoints, and
run_in_executor for CPU-bound/sync-only operations (source analysis,
git clone, LLM chat). Add AsyncGraphQuery, AsyncGitGraph wrapper
classes and async standalone functions while keeping all sync code
intact for the analysis pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gkorland gkorland requested a review from Copilot March 13, 2026 12:20
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 13, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ffc1ca6e-2660-4197-89cd-a37c3903b229

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch staging
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can generate a title for your PR based on the changes.

Add @coderabbitai placeholder anywhere in the title of your PR and CodeRabbit will replace it with a title based on the changes in the PR. You can change the placeholder by changing the reviews.auto_title_placeholder setting.

@railway-app railway-app bot temporarily deployed to Code-Graph / staging March 13, 2026 12:22 Inactive
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR promotes the staging changes that migrate the Python backend from Flask to FastAPI/Uvicorn, updating dependency management, runtime scripts, CI, and endpoint tests to match the new framework.

Changes:

  • Replace Flask app with a FastAPI app (api.index:app) and add SPA static-file serving via FastAPI.
  • Update run/start scripts and CI workflow to launch the server with Uvicorn.
  • Update endpoint tests to use Starlette/FastAPI TestClient and new /api/* paths; add auth/public-access tests.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
api/index.py Reimplements the backend API in FastAPI, adds auth dependencies and SPA static serving.
pyproject.toml Swaps Flask for FastAPI + uvicorn[standard]; adds httpx to test extras.
uv.lock Lockfile update reflecting FastAPI/Uvicorn dependency graph and removal of Flask deps.
start.sh Starts the backend via uvicorn api.index:app instead of Flask.
Makefile Updates dev/prod run commands to Uvicorn.
.github/workflows/playwright.yml Starts/stops Uvicorn in Playwright CI job.
tests/index.py Adds a separate FastAPI app factory used by some endpoint tests.
tests/endpoints/test_repo_info.py Moves to TestClient(api.index.app) and adds auth/public-access tests.
tests/endpoints/test_list_repos.py Moves to TestClient, updates paths, and adds auth tests.
tests/endpoints/test_list_commits.py Moves to TestClient and updates endpoint path.
tests/endpoints/test_graph_entities.py Moves to TestClient and updates endpoint path.
tests/endpoints/test_get_neighbors.py Moves to POST + TestClient and updates endpoint path/payload.
tests/endpoints/test_find_paths.py Moves to TestClient, updates paths, and validates Pydantic 422 behavior.
tests/endpoints/test_auto_complete.py Moves to TestClient and updates endpoint path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +38 to +44
def test_repo_info_public_access(monkeypatch):
"""Public access is granted when CODE_GRAPH_PUBLIC=1."""
monkeypatch.setenv("CODE_GRAPH_PUBLIC", "1")
client = TestClient(api.index.app, raise_server_exceptions=False)
response = client.post("/api/repo_info", json={"repo": "nonexistent"})
# Auth passed (not 401); endpoint may error without a database backend
assert response.status_code != 401
Comment on lines +106 to +112
@app.get('/api/graph_entities')
def graph_entities(repo: str = Query(None), _=Depends(public_or_auth)):
"""Fetch sub-graph entities from a given repository."""

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

# Validate 'node_ids' parameter
if not node_ids:
logging.error("Node IDs is missing in the request.")
return jsonify({"status": "Node IDs is required."}), 400
logging.error("Missing 'repo' parameter in request.")
return JSONResponse({"status": "Missing 'repo' parameter"}, status_code=400)
# Validate 'repo' parameter
@app.get('/api/graph_entities')
def graph_entities(repo: str = Query(None), _=Depends(token_required)):
if not repo:
Comment on lines +3 to +7
import api.index
from pathlib import Path
from tests.index import create_app
from api import Project
from starlette.testclient import TestClient
gkorland and others added 7 commits March 13, 2026 14:26
- Replace deprecated asyncio.get_event_loop() with get_running_loop()
  in all coroutines (api/index.py, api/llm.py, tests/index.py)
- Remove unused `from functools import partial` import (api/index.py)
- Fix inconsistent Cypher keyword casing: "With e" -> "WITH e"
  (api/git_utils/git_graph.py)
- Rename ambiguous parameter `l` to `limit` in
  AsyncGraphQuery.get_sub_graph (api/graph.py)
- Add strict=True to zip(nodes, edges) in AsyncGraphQuery.find_paths
  to catch length mismatches early (api/graph.py)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove unused sync imports from api/index.py (GitGraph, get_repos,
  graph_exists, get_repo_info, prefix_search) and tests/index.py
  (get_repos, graph_exists, get_repo_info, prefix_search)
- Add tests/test_async_graph.py with 7 unit tests covering
  async_graph_exists, async_get_repos, and AsyncGraphQuery (stats,
  close, error cleanup) using mocked FalkorDB client

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Matches the async find_paths which already uses strict=True, so both
versions raise immediately on a nodes/edges length mismatch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ate double connections

- Remove strict=True from zip(nodes, edges) in find_paths (both sync
  and async) — nodes intentionally has one more element than edges
- Revert serve_spa to sync def so FastAPI offloads filesystem I/O to
  thread pool instead of blocking the event loop
- Add graph_exists() method to AsyncGraphQuery to reuse the connection
  instead of opening a separate one via async_graph_exists()
- Update all endpoints in api/index.py and tests/index.py to use
  g.graph_exists() on the query instance
- Fix missing trailing newline in api/llm.py

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tion

- Replace ineffective 'if stats is None' guard in repo_info with
  g.graph_exists() check in both api/index.py and tests/index.py
- Add missing mock_db.aclose assertion in test_async_get_repos_empty

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Migrate FastAPI endpoints from sync to async
@railway-app railway-app bot temporarily deployed to Code-Graph / staging March 13, 2026 14:07 Inactive
gkorland and others added 5 commits March 13, 2026 16:09
Update the README, environment template, and reference docs so they match the current FastAPI/Uvicorn runtime, /api endpoints, supported analyzers, and auth/env behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
docs: sync docs with current FastAPI implementation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants