uvpatel7271 commited on
Commit
1278df1
·
1 Parent(s): 9159c06

added app and api analyser and services

Browse files
Files changed (6) hide show
  1. api/__init__.py +5 -0
  2. api/main.py +27 -0
  3. app/__init__.py +1 -0
  4. app/examples.py +31 -0
  5. app/streamlit_app.py +100 -0
  6. launch.py +35 -0
api/__init__.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ """FastAPI backend package for the multi-domain analyzer."""
2
+
3
+ from .main import app
4
+
5
+ __all__ = ["app"]
api/main.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FastAPI backend for the multi-domain AI code analyzer."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from fastapi import FastAPI
6
+
7
+ from schemas.request import AnalyzeCodeRequest
8
+ from schemas.response import AnalyzeCodeResponse
9
+ from services.analysis_service import AnalysisService
10
+
11
+
12
+ app = FastAPI(title="Multi-Domain AI Code Analyzer", version="2.0.0")
13
+ analysis_service = AnalysisService()
14
+
15
+
16
+ @app.get("/health")
17
+ def health() -> dict[str, str]:
18
+ """Return a simple health payload for deployments and smoke tests."""
19
+
20
+ return {"status": "ok"}
21
+
22
+
23
+ @app.post("/analyze", response_model=AnalyzeCodeResponse)
24
+ def analyze_code(payload: AnalyzeCodeRequest) -> AnalyzeCodeResponse:
25
+ """Analyze code across supported domains and return structured results."""
26
+
27
+ return analysis_service.analyze(payload)
app/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ """Streamlit UI package for the multi-domain analyzer."""
app/examples.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Example snippets for each supported analysis domain."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ EXAMPLES = {
7
+ "DSA": {
8
+ "domain_hint": "dsa",
9
+ "context_window": "Competitive-programming helper for pair lookup on large arrays.",
10
+ "traceback_text": "",
11
+ "code": """def two_sum(nums, target):\n for i in range(len(nums)):\n for j in range(i + 1, len(nums)):\n if nums[i] + nums[j] == target:\n return [i, j]\n return []\n""",
12
+ },
13
+ "Data Science": {
14
+ "domain_hint": "data_science",
15
+ "context_window": "Feature engineering step in a churn-prediction notebook.",
16
+ "traceback_text": "",
17
+ "code": """import pandas as pd\n\ndef encode_features(df):\n values = []\n for _, row in df.iterrows():\n values.append(row['age'] * row['sessions'])\n df['score'] = values\n return df\n""",
18
+ },
19
+ "ML / DL": {
20
+ "domain_hint": "ml_dl",
21
+ "context_window": "Inference utility for a PyTorch classifier used in a batch review job.",
22
+ "traceback_text": "",
23
+ "code": """import torch\n\nclass Predictor:\n def __init__(self, model):\n self.model = model\n\n def predict(self, batch):\n outputs = self.model(batch)\n return outputs.argmax(dim=1)\n""",
24
+ },
25
+ "Web / FastAPI": {
26
+ "domain_hint": "web",
27
+ "context_window": "Backend endpoint for creating review tasks from user-submitted payloads.",
28
+ "traceback_text": "",
29
+ "code": """from fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.post('/tasks')\ndef create_task(request: Request):\n payload = request.json()\n return {'task': payload}\n""",
30
+ },
31
+ }
app/streamlit_app.py ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Streamlit frontend for the multi-domain analyzer platform."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import streamlit as st
6
+
7
+ from app.examples import EXAMPLES
8
+ from schemas.request import AnalyzeCodeRequest
9
+ from services.analysis_service import AnalysisService
10
+
11
+
12
+ analysis_service = AnalysisService()
13
+
14
+
15
+ def _analyze(code: str, context_window: str, traceback_text: str, domain_hint: str):
16
+ """Run the analysis service with validated request payloads."""
17
+
18
+ request = AnalyzeCodeRequest(
19
+ code=code,
20
+ context_window=context_window,
21
+ traceback_text=traceback_text,
22
+ domain_hint=domain_hint, # type: ignore[arg-type]
23
+ )
24
+ return analysis_service.analyze(request)
25
+
26
+
27
+ def main() -> None:
28
+ """Render the Streamlit UI."""
29
+
30
+ st.set_page_config(page_title="Multi-Domain AI Code Analyzer", layout="wide")
31
+ st.title("Multi-Domain AI Code Analyzer & Improvement System")
32
+ st.caption("PyTorch-powered code review across DSA, Data Science, ML/DL, and Web backend code.")
33
+
34
+ example_name = st.selectbox("Example input", list(EXAMPLES.keys()))
35
+ example = EXAMPLES[example_name]
36
+ auto_analyze = st.toggle("Real-time scoring", value=True)
37
+
38
+ left, right = st.columns([1.2, 1.0])
39
+ with left:
40
+ code = st.text_area("Code input", value=example["code"], height=420)
41
+ context_window = st.text_area("Context window", value=example["context_window"], height=100)
42
+ traceback_text = st.text_area("Optional traceback / runtime hint", value=example["traceback_text"], height=100)
43
+ domain_hint = st.selectbox("Domain hint", ["auto", "dsa", "data_science", "ml_dl", "web"], index=["auto", "dsa", "data_science", "ml_dl", "web"].index(example["domain_hint"]))
44
+ analyze_clicked = st.button("Analyze Code", type="primary")
45
+
46
+ result = None
47
+ if code and (analyze_clicked or auto_analyze):
48
+ result = _analyze(code, context_window, traceback_text, domain_hint)
49
+
50
+ with right:
51
+ if result is None:
52
+ st.info("Paste code or load an example to start analysis.")
53
+ else:
54
+ metric_cols = st.columns(4)
55
+ metric_cols[0].metric("Detected domain", result.detected_domain)
56
+ metric_cols[1].metric("ML score", f"{result.score_breakdown.ml_score:.0%}")
57
+ metric_cols[2].metric("Domain score", f"{result.score_breakdown.domain_score:.0%}")
58
+ metric_cols[3].metric("Reward", f"{result.score_breakdown.reward:.0%}")
59
+ st.bar_chart(result.domain_confidences)
60
+ st.caption(result.summary)
61
+
62
+ if result is not None:
63
+ overview_tab, suggestions_tab, domain_tab, static_tab = st.tabs(
64
+ ["Overview", "Suggestions", "Domain Detail", "Static Analysis"]
65
+ )
66
+
67
+ with overview_tab:
68
+ st.subheader("Improvement Plan")
69
+ for step in result.improvement_plan:
70
+ st.write(f"- {step}")
71
+ st.subheader("Complexity")
72
+ st.write(
73
+ {
74
+ "time_complexity": result.static_analysis.time_complexity,
75
+ "space_complexity": result.static_analysis.space_complexity,
76
+ "cyclomatic_complexity": result.static_analysis.cyclomatic_complexity,
77
+ }
78
+ )
79
+
80
+ with suggestions_tab:
81
+ st.subheader("Suggestions")
82
+ for suggestion in result.domain_analysis.suggestions:
83
+ st.write(f"- {suggestion}")
84
+ if result.domain_analysis.issues:
85
+ st.subheader("Issues")
86
+ for issue in result.domain_analysis.issues:
87
+ st.write(f"- [{issue.severity}] {issue.title}: {issue.description}")
88
+
89
+ with domain_tab:
90
+ st.subheader("Domain Highlights")
91
+ st.json(result.domain_analysis.highlights)
92
+ st.write(f"Domain score: {result.domain_analysis.domain_score:.0%}")
93
+
94
+ with static_tab:
95
+ st.subheader("Static Analysis")
96
+ st.json(result.static_analysis.model_dump())
97
+
98
+
99
+ if __name__ == "__main__":
100
+ main()
launch.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Launch the FastAPI backend and Streamlit UI in one Docker container."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import subprocess
6
+ import sys
7
+
8
+
9
+ def main() -> int:
10
+ """Start the API backend in the background and keep Streamlit in the foreground."""
11
+
12
+ api_process = subprocess.Popen(
13
+ ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8001"],
14
+ )
15
+ try:
16
+ return subprocess.call(
17
+ [
18
+ "streamlit",
19
+ "run",
20
+ "app/streamlit_app.py",
21
+ "--server.port",
22
+ "8000",
23
+ "--server.address",
24
+ "0.0.0.0",
25
+ "--server.headless",
26
+ "true",
27
+ ]
28
+ )
29
+ finally:
30
+ api_process.terminate()
31
+ api_process.wait(timeout=10)
32
+
33
+
34
+ if __name__ == "__main__":
35
+ sys.exit(main())