File size: 4,926 Bytes
16a41ed | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | """
api/models.py β Pydantic request/response schemas for every endpoint.
What Pydantic does:
Pydantic validates incoming request data automatically.
If a request body is missing a required field, or has the wrong type,
FastAPI returns a clear 422 error BEFORE your route code even runs.
No manual validation code needed.
It also generates the JSON schema that powers the /docs Swagger UI β
every field shows up with its type and description automatically.
Why one file for all models?
Same reason as prompts.py β one place to change shapes.
If the frontend changes what it sends, you update here, not in 5 routes.
Naming convention:
*Request β what the frontend sends IN (request body)
*Response β what the backend sends OUT (response body)
"""
from pydantic import BaseModel, HttpUrl, Field
from typing import Optional
# -----------------------------------------------------------------------
# INGEST β POST /api/v1/ingest
# Frontend sends a GitHub URL, backend runs the full pipeline.
# -----------------------------------------------------------------------
class IngestRequest(BaseModel):
github_url: str = Field(
...,
description="Public GitHub repository URL to analyse.",
example="https://github.com/tiangolo/fastapi",
)
class IngestResponse(BaseModel):
status: str = Field(..., example="success")
repo_name: str = Field(..., example="fastapi")
files_indexed: int = Field(..., description="Number of source files found.")
chunks_stored: int = Field(..., description="Number of code chunks embedded and stored.")
graph_ready: bool = Field(..., description="True if dependency graph was built.")
message: str = Field(..., example="Repository indexed successfully.")
# -----------------------------------------------------------------------
# QUERY β POST /api/v1/ask
# Frontend sends a question about a previously indexed repo.
# -----------------------------------------------------------------------
class AskRequest(BaseModel):
repo_name: str = Field(
...,
description="The repo name as returned by /ingest.",
example="fastapi",
)
question: str = Field(
...,
description="Natural language question about the codebase.",
example="Where is the authentication logic handled?",
)
class AskResponse(BaseModel):
status: str = Field(..., example="success")
repo_name: str
question: str
answer: str = Field(..., description="LLM-generated answer with file citations.")
chunks_used: int = Field(..., description="Number of code chunks used as context.")
# -----------------------------------------------------------------------
# GRAPH β GET /api/v1/graph?repo_name=fastapi
# Returns the interactive dependency graph as an HTML string.
# -----------------------------------------------------------------------
class GraphResponse(BaseModel):
status: str
repo_name: str
html: str = Field(..., description="Self-contained Pyvis HTML for iframe rendering.")
stats: dict = Field(..., description="Graph statistics: nodes, edges, cycles, most_depended_on.")
# -----------------------------------------------------------------------
# BUGS β GET /api/v1/bugs?repo_name=fastapi
# Returns a list of detected issues in the codebase.
# -----------------------------------------------------------------------
class BugItem(BaseModel):
file: str = Field(..., example="src/auth.py")
line: int = Field(..., example=34)
severity: str = Field(..., example="high") # "high", "medium", "low"
issue: str = Field(..., example="Unhandled exception in database call.")
suggestion: str = Field(..., example="Wrap in try/except and log the error.")
class BugsResponse(BaseModel):
status: str
repo_name: str
bugs: list[BugItem]
total: int = Field(..., description="Total number of issues found.")
# -----------------------------------------------------------------------
# DIAGRAM β GET /api/v1/diagram?repo_name=fastapi
# Returns architecture summary + Mermaid diagram syntax.
# -----------------------------------------------------------------------
class DiagramResponse(BaseModel):
status: str
repo_name: str
summary: str = Field(..., description="3-5 sentence architecture overview.")
mermaid: str = Field(..., description="Mermaid flowchart syntax string for frontend rendering.")
# -----------------------------------------------------------------------
# ERROR β used by all routes when something goes wrong.
# Returned with appropriate HTTP status codes (400, 404, 500).
# -----------------------------------------------------------------------
class ErrorResponse(BaseModel):
status: str = Field(default="error")
message: str |