n3mo 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- n3mo/__init__.py +0 -0
- n3mo/api/__init__.py +1 -0
- n3mo/api/webhook_handler.py +84 -0
- n3mo/cli.py +1083 -0
- n3mo/crawler.py +143 -0
- n3mo/database.py +437 -0
- n3mo/db/__init__.py +1 -0
- n3mo/db/schema.sql +70 -0
- n3mo/docker-compose.yml +38 -0
- n3mo/graph_visualizer.py +1287 -0
- n3mo/ingest_files.py +136 -0
- n3mo/mcp_server.py +238 -0
- n3mo/resolve_calls.py +46 -0
- n3mo/resolve_imports.py +21 -0
- n3mo/run_indexer.py +344 -0
- n3mo/symbol_extractor.py +554 -0
- n3mo-1.0.0.dist-info/METADATA +37 -0
- n3mo-1.0.0.dist-info/RECORD +22 -0
- n3mo-1.0.0.dist-info/WHEEL +5 -0
- n3mo-1.0.0.dist-info/entry_points.txt +2 -0
- n3mo-1.0.0.dist-info/licenses/LICENSE +661 -0
- n3mo-1.0.0.dist-info/top_level.txt +1 -0
n3mo/__init__.py
ADDED
|
File without changes
|
n3mo/api/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# N3MO Web API Package
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
from fastapi import FastAPI, Request, Header, HTTPException
|
|
4
|
+
|
|
5
|
+
# Set up logging
|
|
6
|
+
logger = logging.getLogger("n3mo.api")
|
|
7
|
+
logging.basicConfig(level=logging.INFO)
|
|
8
|
+
|
|
9
|
+
app = FastAPI(
|
|
10
|
+
title="N3MO GitHub App Webhook API",
|
|
11
|
+
description="Listens to GitHub webhooks to run incremental impact analysis on Pull Requests.",
|
|
12
|
+
version="0.1.0"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
# Configuration
|
|
16
|
+
GITHUB_WEBHOOK_SECRET = os.getenv("GITHUB_WEBHOOK_SECRET", "")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@app.get("/health")
|
|
20
|
+
def health_check():
|
|
21
|
+
"""Verify service health."""
|
|
22
|
+
return {"status": "healthy", "service": "n3mo-api"}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@app.post("/webhook")
|
|
26
|
+
async def github_webhook(
|
|
27
|
+
request: Request,
|
|
28
|
+
x_github_event: str = Header(None),
|
|
29
|
+
x_hub_signature_256: str = Header(None)
|
|
30
|
+
):
|
|
31
|
+
"""
|
|
32
|
+
Handle incoming GitHub App webhooks.
|
|
33
|
+
Filters for pull_request events to trigger blast-radius checks.
|
|
34
|
+
"""
|
|
35
|
+
if not x_github_event:
|
|
36
|
+
raise HTTPException(status_code=400, detail="Missing X-GitHub-Event header")
|
|
37
|
+
|
|
38
|
+
# Verify webhook signature if secret is configured
|
|
39
|
+
if GITHUB_WEBHOOK_SECRET:
|
|
40
|
+
if not x_hub_signature_256:
|
|
41
|
+
raise HTTPException(status_code=401, detail="Missing X-Hub-Signature-256 header")
|
|
42
|
+
# Signature verification logic goes here
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
payload = await request.json()
|
|
46
|
+
logger.info(f"Received GitHub event: {x_github_event}")
|
|
47
|
+
|
|
48
|
+
if x_github_event == "pull_request":
|
|
49
|
+
action = payload.get("action")
|
|
50
|
+
# Trigger on PR opening or adding new commits
|
|
51
|
+
if action in ["opened", "synchronize"]:
|
|
52
|
+
return handle_pull_request(payload)
|
|
53
|
+
|
|
54
|
+
return {"message": f"Event '{x_github_event}' ignored"}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def handle_pull_request(payload: dict) -> dict:
|
|
58
|
+
"""
|
|
59
|
+
Extract diff details, run incremental indexing, and compute impact blast radius.
|
|
60
|
+
"""
|
|
61
|
+
pr_number = payload.get("number")
|
|
62
|
+
repo_name = payload.get("repository", {}).get("full_name")
|
|
63
|
+
clone_url = payload.get("repository", {}).get("clone_url")
|
|
64
|
+
base_sha = payload.get("pull_request", {}).get("base", {}).get("sha")
|
|
65
|
+
head_sha = payload.get("pull_request", {}).get("head", {}).get("sha")
|
|
66
|
+
|
|
67
|
+
logger.info(f"Analyzing PR #{pr_number} for {repo_name} (from {base_sha} to {head_sha})")
|
|
68
|
+
|
|
69
|
+
# Placeholder logic for workflow:
|
|
70
|
+
# 1. Fetch changed files from GitHub API
|
|
71
|
+
# 2. Run AST parser incrementally for changed files
|
|
72
|
+
# 3. Compute blast radius CTE from database for changed symbols
|
|
73
|
+
# 4. Format PR Markdown comment and post to GitHub API
|
|
74
|
+
|
|
75
|
+
affected_symbols = ["predict_song_score", "get_recommendations"] # Example mockup
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
"status": "processed",
|
|
79
|
+
"pr": pr_number,
|
|
80
|
+
"repo": repo_name,
|
|
81
|
+
"clone_url": clone_url,
|
|
82
|
+
"changed_symbols": affected_symbols,
|
|
83
|
+
"message": f"Successfully calculated blast radius for {len(affected_symbols)} symbols."
|
|
84
|
+
}
|