-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Summary
Extract HTTP route definitions from Python web framework files using tree-sitter. Supports FastAPI, Flask, and Django.
New file
src/specleft/discovery/miners/python/routes.py
import uuid
from specleft.discovery.models import SupportedLanguage, MinerResult, DiscoveredItem, ItemKind, ApiRouteMeta
from specleft.discovery.context import MinerContext
class PythonRouteMiner:
miner_id = uuid.UUID("007ab65e-e4e8-4b7e-9c33-163635168071")
name = "python_api_routes"
languages = frozenset({SupportedLanguage.PYTHON})
def mine(self, ctx: MinerContext) -> MinerResult: ...Framework detection
Read from ctx.frameworks[SupportedLanguage.PYTHON] to determine which framework detection strategy to apply. Do NOT re-parse pyproject.toml or scan imports — the FrameworkDetector has already resolved this.
If ctx.frameworks includes "fastapi", scan for FastAPI patterns. If "flask", scan Flask patterns. If "django", scan Django patterns. Multiple frameworks may be present — scan for all.
File targeting
Use ctx.file_index.files_by_language(SupportedLanguage.PYTHON) to get all Python files. Scan all of them for route patterns (not just test files).
Detection strategies per framework
FastAPI / APIRouter:
Tree-sitter query: decorated function where decorator is an attribute access on app or router, method name is get|post|put|patch|delete|options|head. First string argument is the path.
Flask:
@app.route("/path", methods=["GET"]) or @blueprint.route(...). Parse methods keyword argument; default to ["GET"] if absent.
Django:
urlpatterns = [path("...", view_func, name="..."), re_path(...)]. Parse list elements.
Typed metadata
Each item's metadata dict must conform to ApiRouteMeta:
ApiRouteMeta(
http_method = "GET",
path = "/users/{id}",
framework = "fastapi",
handler_name = "get_user",
has_docstring = True,
docstring = "Retrieve a user by ID",
response_model = "UserResponse",
)name: "{METHOD} {path}" (e.g. "GET /users/{id}")
language: SupportedLanguage.PYTHON
Acceptance criteria
- FastAPI fixture with 3 routes (GET, POST, PATCH) returns 3 items with correct methods and paths
- All items have
language=SupportedLanguage.PYTHON - Each item's
metadatavalidates againstApiRouteMeta - Flask blueprint route
@bp.route("/items", methods=["GET", "POST"])→http_method=["GET", "POST"] - Django
urlpatternswithpath()andre_path()both produce items - Missing
methodskwarg on Flask route defaults to["GET"] -
response_modelcaptured for FastAPI routes - Uses
ctx.file_indexandctx.frameworks— no direct filesystem or manifest parsing - Tests in
tests/discovery/miners/test_python_routes.py - Update scenarios and tests in
features/feature-spec-discovery.mdto cover the functionality introduced by this issue