mirror of
https://github.com/Egonex-AI/Understand-Anything.git
synced 2026-06-22 10:58:03 +08:00
feat: extend analysis pipeline for Python codebases and frameworks
- project-scanner: detect Python frameworks from requirements.txt, pyproject.toml, setup.py, Pipfile (django, fastapi, flask, sqlalchemy, celery, pydantic, etc.); add pyproject.toml to project name extraction - SKILL.md: expand Python entry points (manage.py, app.py, wsgi.py, asgi.py, run.py, __main__.py); add FastAPI and Flask framework guidance to Phase 2 and Phase 4 inline hints; wire addendum file injection for Django, FastAPI, and Flask when detected - architecture-analyzer: add __init__.py and manage.py as entry-point file-level patterns; add Python directory patterns (migrations, signals, serializers, management, templatetags); clarify *.d.ts is TS-only - tour-builder: add Python entry point filename patterns to +3 scoring (manage.py, app.py, wsgi.py, asgi.py, run.py, __main__.py) - file-analyzer: add __init__.py barrel/entry-point detection alongside index.ts; show Python script execution alternative in example - new: django-analyzer-addendum.md — canonical file roles, edge patterns (URL routing graph, signal wiring, ORM relationships), layer guide, and language lesson patterns for Django projects - new: fastapi-analyzer-addendum.md — canonical file roles, DI tree edge patterns, layer guide, and language lesson patterns for FastAPI and Flask - new: PYTHON-SUPPORT-CHANGES.md — reviewer doc covering every change, rationale, regression risk, and a testing checklist https://claude.ai/code/session_015ihoTRnr7yYx3TkcadKYbn
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
# Python Codebase Support — Change Review Guide
|
||||
|
||||
This document explains every change made to add Python and Python framework support. It is written for a reviewer who wants to verify correctness, spot regressions, and understand the rationale for each decision.
|
||||
|
||||
---
|
||||
|
||||
## Background: What Was Wrong
|
||||
|
||||
The tool worked well for TypeScript/JavaScript codebases. For Python codebases it would:
|
||||
- Fail to detect frameworks (Django, FastAPI, Flask) — `frameworks: []` always
|
||||
- Miss common Python entry points (`manage.py`, `app.py`, `wsgi.py`) — defaulting to no entry point
|
||||
- Score Python entry points much lower than TS equivalents in the tour builder (4 Python patterns vs 8 JS/TS patterns)
|
||||
- Miss Python's `__init__.py` as a barrel/entry-point equivalent (only `index.ts`/`index.js` were recognized)
|
||||
- Have no layer guidance for FastAPI or Flask (only Django had a brief mention)
|
||||
- Ignore `pyproject.toml` for project name extraction
|
||||
|
||||
The bias was **only in agent prompts** (markdown files). The graph schema, dashboard, search engine, and core plugin architecture are language-agnostic and required no changes.
|
||||
|
||||
---
|
||||
|
||||
## Files Changed
|
||||
|
||||
### 1. `project-scanner-prompt.md`
|
||||
|
||||
**What changed:**
|
||||
|
||||
**Step 5 (Framework Detection)** — Extended the Python manifest reading from "confirms Python project" to actually detecting frameworks:
|
||||
- `requirements.txt`: now reads line-by-line, strips version specifiers, and matches against a Python framework keyword list: `django`, `djangorestframework`, `fastapi`, `flask`, `sqlalchemy`, `alembic`, `celery`, `pydantic`, `uvicorn`, `gunicorn`, `aiohttp`, `tornado`, `starlette`, `pytest`, `hypothesis`, `channels`
|
||||
- `pyproject.toml`: now parses `[project].dependencies` and `[tool.poetry.dependencies]`, applies the same keyword matching, and also checks for `[tool.pytest.ini_options]` (pytest) and `[tool.django]` (Django)
|
||||
- `setup.py`, `setup.cfg`, `Pipfile`: now apply the same Python framework keyword matching
|
||||
|
||||
**Step 7 (Project Name)** — Added `pyproject.toml` to the priority order between `go.mod` and directory name. Checks `[project].name` first, then `[tool.poetry].name`.
|
||||
|
||||
**Why:** Without framework detection, `frameworks: []` is passed to every downstream agent. The framework-specific guidance injected in Phase 2 and Phase 4 of SKILL.md is only useful when `frameworks` is non-empty.
|
||||
|
||||
**Regression risk:** None. The JS framework detection in `package.json` is unchanged. The Python additions are additive.
|
||||
|
||||
**How to verify:** Run `/understand` on a Django project with `requirements.txt` containing `django`. Check that `scan-result.json` has `frameworks: ["Django"]`.
|
||||
|
||||
---
|
||||
|
||||
### 2. `SKILL.md`
|
||||
|
||||
**What changed:**
|
||||
|
||||
**Phase 0 (entry point detection, line 57)** — Added Python entry points to the pattern list:
|
||||
- Before: `src/index.ts`, `src/main.ts`, `src/App.tsx`, `main.py`, `main.go`, `src/main.rs`, `index.js`
|
||||
- After: added `manage.py`, `app.py`, `wsgi.py`, `asgi.py`, `run.py`, `__main__.py`
|
||||
|
||||
**Why:** A Django project's real entry point is `manage.py`. A FastAPI/Flask project uses `app.py` or `run.py`. Without these, `$ENTRY_POINT` is empty for most Python projects, and the tour builder gets no starting hint.
|
||||
|
||||
**Phase 2 (file-analyzer framework guidance)** — Extended the inline framework hints:
|
||||
- Django: added `serializers.py`, `signals.py`, `admin.py`, `migrations/` descriptions
|
||||
- Added FastAPI: describes `@router` decorator files, Pydantic schemas, `Depends()` providers
|
||||
- Added Flask: describes `@blueprint.route`, `blueprints/`, SQLAlchemy `models.py`
|
||||
- Added addendum injection: if `Django` detected, reads `./django-analyzer-addendum.md` and appends to the file-analyzer prompt. If `FastAPI` or `Flask` detected, reads `./fastapi-analyzer-addendum.md` and appends.
|
||||
|
||||
**Phase 4 (architecture-analyzer framework hints)** — Extended the inline layer hints:
|
||||
- Django: added `serializers.py`, `signals.py`, `migrations/` → specific layers
|
||||
- Added FastAPI: router files → API, Pydantic schemas → Types, `dependencies.py` → Service, DB files → Data
|
||||
- Added Flask: blueprint route files → API, `models.py` → Data, `forms.py` → UI, `extensions.py` → Config
|
||||
- Added addendum injection: same logic as Phase 2
|
||||
|
||||
**Regression risk:** Low. The addendum injection only triggers when those frameworks are in the detected list. The inline guidance additions are additive strings — they don't change the structure of the injected context.
|
||||
|
||||
**How to verify:**
|
||||
- Run on a FastAPI project: check `layers.json` has a `layer:types` or `layer:api` with Pydantic schema files assigned correctly
|
||||
- Run on a TS project: check that no Django/FastAPI addendum content appears in the analysis (it shouldn't, since `frameworks` won't contain those values)
|
||||
|
||||
---
|
||||
|
||||
### 3. `architecture-analyzer-prompt.md`
|
||||
|
||||
**What changed:**
|
||||
|
||||
**Directory pattern table** — Added Python-specific directory names:
|
||||
|
||||
| Added | Pattern Label | Why |
|
||||
|-------|---------------|-----|
|
||||
| `migrations` | `data` | Django/Alembic migration directories hold schema history — Data Layer |
|
||||
| `management`, `commands` | `config` | Django management command directories |
|
||||
| `templatetags` | `utility` | Django custom template tag directories |
|
||||
| `signals` | `service` | Signal handler modules — cross-cutting service logic |
|
||||
| `serializers` | `api` | DRF serializer directories |
|
||||
|
||||
**File-level pattern matching** — Three changes:
|
||||
1. Added `test_*.py` to the test pattern (Python's `pytest` naming convention)
|
||||
2. Added `__init__.py` at a directory root → `entry` pattern (Python package barrel equivalent of `index.ts`)
|
||||
3. Added `manage.py` → `entry` and `wsgi.py`/`asgi.py` → `config`
|
||||
4. Clarified `*.d.ts → types` with "(TypeScript declaration files only)" — making it explicit this is TS-specific so an LLM doesn't misapply it to Python
|
||||
|
||||
**Why:** Without `__init__.py → entry`, the architecture analyzer would never recognize any Python file as an entry point via file-level patterns. The `hooks` pattern label was left as-is (it won't trigger on Python projects since they don't conventionally have a `hooks/` directory).
|
||||
|
||||
**Note on Node.js script:** The architecture analyzer's structural analysis script is hardcoded to `node`. This is correct to leave as-is — the script processes the JSON graph structure (file nodes, import edges), not the source language of the codebase being analyzed. The script's input/output is always JSON regardless of whether the project is Python or TypeScript.
|
||||
|
||||
**Regression risk:** Very low. Added rows to the directory pattern table and clarified file-level pattern descriptions. No existing patterns were removed or modified.
|
||||
|
||||
**How to verify:** Run on a Django project. Check that `migrations/` directory files land in `layer:data` and that `manage.py` gets tagged `entry`.
|
||||
|
||||
---
|
||||
|
||||
### 4. `tour-builder-prompt.md`
|
||||
|
||||
**What changed:**
|
||||
|
||||
**Entry point candidate scoring (Section C)** — Added Python entry points to the +3 filename list:
|
||||
- Added: `manage.py`, `app.py`, `wsgi.py`, `asgi.py`, `run.py`, `__main__.py`
|
||||
|
||||
Before this change, the entry point scoring had 8 TS/JS patterns vs 4 for all other languages. After: 8 TS/JS + 6 Python + 4 others.
|
||||
|
||||
**Why:** The tour builder uses entry point scores to decide Step 1 of the tour. For a Django project where `manage.py` exists, it should score highly. Without this, the tour might start from a random high-fan-in utility file instead of the actual entry point.
|
||||
|
||||
**The `languageLesson` example** was left as-is (TypeScript barrel files). This is just an illustrative example in the output format section — it does not affect how Python tours are generated. The language lessons section already lists Python-specific patterns (decorators, generators, context managers, metaclasses, protocols).
|
||||
|
||||
**Regression risk:** None. The scoring list is additive. TS/JS entry points retain their +3 scores.
|
||||
|
||||
**How to verify:** Run on a Django project. Check that `tour.json` starts from `manage.py` or `apps.py`/`wsgi.py` rather than a utility file.
|
||||
|
||||
---
|
||||
|
||||
### 5. `file-analyzer-prompt.md`
|
||||
|
||||
**What changed:**
|
||||
|
||||
**Tags indicators — barrel/entry-point detection** — Extended the `index.ts` rule:
|
||||
- Before: `Named index.ts at a directory root with re-exports = entry-point`
|
||||
- After: Added `__init__.py` at a package root with imports or re-exports = `entry-point`, and `manage.py` = `entry-point`
|
||||
|
||||
**Script execution example** — Added the Python equivalent command alongside the Node.js example. The base prompt already says "Choose the best language for this task — Node.js is recommended for TypeScript/JavaScript projects, Python for Python projects" (line 15), but the execution example only showed `node`. This created a contradiction. Now both are shown.
|
||||
|
||||
**Regression risk:** None. Additive changes only.
|
||||
|
||||
**How to verify:** Run on a Python project with a package structure. Check that `__init__.py` files at package roots get the `entry-point` or `barrel` tag rather than being treated as empty boilerplate files.
|
||||
|
||||
---
|
||||
|
||||
## New Files Created
|
||||
|
||||
### `django-analyzer-addendum.md`
|
||||
|
||||
A detailed reference injected into the file-analyzer and architecture-analyzer when Django is detected. Contains:
|
||||
- Canonical file roles table (15+ Django file types with appropriate tags)
|
||||
- Edge patterns to look for (URL routing graph, signal wiring, ORM relationships, serializer→model binding)
|
||||
- Layer assignment guide (7 layers: api, data, service, ui, middleware, config, test)
|
||||
- Notable `languageLesson` patterns (fat models, ORM lazy evaluation, CBV mixins, signal anti-patterns, app isolation)
|
||||
|
||||
**How it's injected:** SKILL.md reads this file and appends it to the base `file-analyzer-prompt.md` and `architecture-analyzer-prompt.md` content when `Django` appears in the detected frameworks list.
|
||||
|
||||
### `fastapi-analyzer-addendum.md`
|
||||
|
||||
A detailed reference for FastAPI and Flask projects, injected when either framework is detected. Contains two sections:
|
||||
|
||||
**FastAPI section:**
|
||||
- Canonical file roles (router files, Pydantic schemas, CRUD, dependencies, database session)
|
||||
- Edge patterns (router inclusion chain, DI tree, Pydantic inheritance, CRUD→model binding)
|
||||
- Layer assignment guide (7 layers)
|
||||
- Notable `languageLesson` patterns (DI as composition, Pydantic validation, async vs sync, route order)
|
||||
|
||||
**Flask section:**
|
||||
- Canonical file roles (blueprints, application factory, WTForms, Marshmallow)
|
||||
- Edge patterns (blueprint registration, extension coupling, before/after request hooks)
|
||||
- Layer assignment guide
|
||||
- Notable `languageLesson` patterns (factory pattern, blueprint modularity, extension `init_app` protocol)
|
||||
|
||||
**How it's injected:** Same mechanism as the Django addendum — SKILL.md appends it when `FastAPI` or `Flask` is in the detected frameworks list.
|
||||
|
||||
---
|
||||
|
||||
## What Was NOT Changed (And Why)
|
||||
|
||||
| Component | Rationale |
|
||||
|-----------|-----------|
|
||||
| Graph schema (`types.ts`, `schema.ts`) | Already language-agnostic. All 18 edge types work for Python patterns. |
|
||||
| `packages/core/src/plugins/tree-sitter-plugin.ts` | Still TS/JS only. Adding Python tree-sitter support is Phase 3 (separate PR). |
|
||||
| `packages/core/src/plugins/registry.ts` | Extension map already has `.py → python`. A Python plugin will register here in Phase 3. |
|
||||
| `packages/core/src/analyzer/language-lesson.ts` | Concept detection patterns. Phase 3 work. |
|
||||
| Dashboard, search engine, skills | Already language-agnostic. |
|
||||
| `tour-builder-prompt.md` language lessons example | The TypeScript barrel file example is illustrative only. Python tours will produce Python-specific `languageLesson` strings based on the language-lessons list (which already includes Python patterns). |
|
||||
| Architecture analyzer `node` script execution | The script analyzes the graph JSON, not the source language. `node` is always correct here. |
|
||||
| `hooks` directory pattern label | React-specific but harmless — Python projects don't conventionally have `hooks/` directories, so this label will never trigger on Python codebases. |
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist for Reviewer
|
||||
|
||||
For a Django project (e.g., a real Django app with `requirements.txt`):
|
||||
- [ ] `scan-result.json` has `frameworks: ["Django"]` (or similar)
|
||||
- [ ] `manage.py` is detected as `$ENTRY_POINT` in SKILL.md Phase 0
|
||||
- [ ] `manage.py` node gets tags including `entry-point`
|
||||
- [ ] `urls.py` files get `api-handler`, `routing` tags
|
||||
- [ ] `models.py` files get `data-model` tag
|
||||
- [ ] `migrations/` directory files land in `layer:data`
|
||||
- [ ] Tour Step 1 starts from `manage.py` or `wsgi.py`
|
||||
- [ ] No TypeScript-specific guidance appears in the analysis output
|
||||
|
||||
For a FastAPI project:
|
||||
- [ ] `scan-result.json` has `frameworks: ["FastAPI"]`
|
||||
- [ ] Router files get `api-handler`, `routing` tags
|
||||
- [ ] Pydantic schema files get `type-definition`, `serialization` tags
|
||||
- [ ] `dependencies.py` or `deps.py` gets `service` tag
|
||||
- [ ] `depends_on` edges appear between router files and their dependencies
|
||||
- [ ] `layer:types` exists with schema files
|
||||
|
||||
For an existing TypeScript project (regression check):
|
||||
- [ ] No Django/FastAPI addendum content appears in analysis
|
||||
- [ ] `frameworks: ["React"]` (or whatever was there before) unchanged
|
||||
- [ ] `src/index.ts` still detected as entry point
|
||||
- [ ] All existing layer assignments and tour steps unchanged
|
||||
@@ -54,7 +54,7 @@ Determine whether to run a full analysis or incremental update.
|
||||
find $PROJECT_ROOT -maxdepth 2 -type f -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' | head -100
|
||||
```
|
||||
Store as `$DIR_TREE`.
|
||||
- Detect the project entry point by checking for common patterns: `src/index.ts`, `src/main.ts`, `src/App.tsx`, `main.py`, `main.go`, `src/main.rs`, `index.js`. Store first match as `$ENTRY_POINT`.
|
||||
- Detect the project entry point by checking for common patterns (in order): `src/index.ts`, `src/main.ts`, `src/App.tsx`, `index.js`, `main.py`, `manage.py`, `app.py`, `wsgi.py`, `asgi.py`, `run.py`, `__main__.py`, `main.go`, `src/main.rs`. Store first match as `$ENTRY_POINT`.
|
||||
|
||||
---
|
||||
|
||||
@@ -98,7 +98,7 @@ After the subagent completes, read `$PROJECT_ROOT/.understand-anything/intermedi
|
||||
|
||||
Batch the file list from Phase 1 into groups of **5-10 files each** (aim for balanced batch sizes).
|
||||
|
||||
For each batch, dispatch a subagent using the prompt template at `./file-analyzer-prompt.md`. Run up to **3 subagents concurrently** using parallel dispatch. Read the template once, then for each batch pass the full template content as the subagent's prompt, appending the following additional context:
|
||||
For each batch, dispatch a subagent using the prompt template at `./file-analyzer-prompt.md`. Run up to **3 subagents concurrently** using parallel dispatch. Read the template once. If any detected framework is `Django`, also read `./django-analyzer-addendum.md` and append its full content after the base template. If any detected framework is `FastAPI` or `Flask`, also read `./fastapi-analyzer-addendum.md` and append its full content after the base template. Then for each batch pass the combined template content as the subagent's prompt, appending the following additional context:
|
||||
|
||||
> **Additional context from main session:**
|
||||
>
|
||||
@@ -109,7 +109,9 @@ For each batch, dispatch a subagent using the prompt template at `./file-analyze
|
||||
> Framework-specific guidance:
|
||||
> - If React/Next.js: files in `app/` or `pages/` are routes, `components/` are UI, `lib/` or `utils/` are utilities
|
||||
> - If Express/Fastify: files in `routes/` are API endpoints, `middleware/` is middleware, `models/` or `db/` is data
|
||||
> - If Python Django: `views.py` are controllers, `models.py` is data, `urls.py` is routing, `templates/` is UI
|
||||
> - If Python Django: `views.py` are controllers, `models.py` is data, `urls.py` is routing, `templates/` is UI, `serializers.py` is API serialization, `signals.py` is event wiring, `admin.py` is admin registration, `migrations/` is schema history
|
||||
> - If Python FastAPI: files with `@router.get/post/...` decorators are endpoints, `schemas.py` or `models.py` with Pydantic classes are request/response types, `dependencies.py` or `deps.py` holds `Depends()` providers, `routers/` or `api/` groups route modules
|
||||
> - If Python Flask: files with `@app.route` or `@blueprint.route` are endpoints, `blueprints/` or `views/` groups route modules, `models.py` with SQLAlchemy classes is data
|
||||
> - If Go: `cmd/` is entry points, `internal/` is private packages, `pkg/` is public packages
|
||||
>
|
||||
> Use this context to produce more accurate summaries and better classify file roles.
|
||||
@@ -158,7 +160,7 @@ Merge all file-analyzer results into a single set of nodes and edges. Then perfo
|
||||
|
||||
## Phase 4 — ARCHITECTURE
|
||||
|
||||
Dispatch a subagent using the prompt template at `./architecture-analyzer-prompt.md`. Read the template file and pass the full content as the subagent's prompt, appending the following additional context:
|
||||
Dispatch a subagent using the prompt template at `./architecture-analyzer-prompt.md`. If any detected framework is `Django`, also read `./django-analyzer-addendum.md` and append its full content after the base template. If any detected framework is `FastAPI` or `Flask`, also read `./fastapi-analyzer-addendum.md` and append its full content after the base template. Pass the combined content as the subagent's prompt, appending the following additional context:
|
||||
|
||||
> **Additional context from main session:**
|
||||
>
|
||||
@@ -172,7 +174,9 @@ Dispatch a subagent using the prompt template at `./architecture-analyzer-prompt
|
||||
> Framework-specific layer hints:
|
||||
> - If React/Next.js: `app/` or `pages/` → UI Layer, `api/` → API Layer, `lib/` → Service Layer, `components/` → UI Layer
|
||||
> - If Express: `routes/` → API Layer, `controllers/` → Service Layer, `models/` → Data Layer, `middleware/` → Middleware Layer
|
||||
> - If Python Django: `views/` → API Layer, `models/` → Data Layer, `templates/` → UI Layer, `management/` → CLI Layer
|
||||
> - If Python Django: `views/` or `views.py` → API Layer, `models/` or `models.py` → Data Layer, `templates/` → UI Layer, `management/` → CLI Layer, `serializers.py` → API Layer, `signals.py` → Event Layer, `migrations/` → Data Layer
|
||||
> - If Python FastAPI: files with router decorators → API Layer, Pydantic schema files → Types Layer, `dependencies.py` or `deps.py` → Service Layer, `routers/` or `api/` → API Layer, database session/engine files → Data Layer
|
||||
> - If Python Flask: files with `@blueprint.route` → API Layer, `models.py` → Data Layer, `forms.py` → UI Layer, `extensions.py` → Config Layer
|
||||
> - If Go: `cmd/` → Entry Points, `internal/` → Service Layer, `pkg/` → Shared Library, `api/` → API Layer
|
||||
>
|
||||
> Use the directory tree and framework hints to inform layer assignments. Directory structure is strong evidence for layer boundaries.
|
||||
|
||||
@@ -82,11 +82,18 @@ Classify each directory name against known architectural patterns:
|
||||
| `hooks` | `hooks` |
|
||||
| `store`, `state`, `reducers`, `actions`, `slices` | `state` |
|
||||
| `assets`, `static`, `public` | `assets` |
|
||||
| `migrations` | `data` |
|
||||
| `management`, `commands` | `config` |
|
||||
| `templatetags` | `utility` |
|
||||
| `signals` | `service` |
|
||||
| `serializers` | `api` |
|
||||
|
||||
Also check file-level patterns:
|
||||
- Files matching `*.test.*` or `*.spec.*` -> `test`
|
||||
- Files matching `*.d.ts` -> `types`
|
||||
- Files named `index.ts`/`index.js` at a package root -> `entry`
|
||||
- Files matching `*.test.*` or `*.spec.*` or `test_*.py` -> `test`
|
||||
- Files matching `*.d.ts` -> `types` (TypeScript declaration files only)
|
||||
- Files named `index.ts`, `index.js`, or `__init__.py` at a package/directory root -> `entry`
|
||||
- Files named `manage.py` at the project root -> `entry` (Django management entry point)
|
||||
- Files named `wsgi.py` or `asgi.py` -> `config` (Python WSGI/ASGI server config)
|
||||
|
||||
**F. Dependency Direction**
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Django Framework Addendum
|
||||
|
||||
> Injected into file-analyzer and architecture-analyzer prompts when Django is detected.
|
||||
> Do NOT use as a standalone prompt — always appended to the base prompt template.
|
||||
|
||||
## Django Project Structure
|
||||
|
||||
When analyzing a Django project, apply these additional conventions on top of the base analysis rules.
|
||||
|
||||
### Canonical File Roles
|
||||
|
||||
| File / Pattern | Role | Tags |
|
||||
|---|---|---|
|
||||
| `manage.py` | CLI entry point for dev server, migrations, management commands | `entry-point`, `config` |
|
||||
| `*/settings.py`, `*/settings/*.py` | Project-wide configuration (DB, installed apps, middleware) | `config` |
|
||||
| `*/urls.py` | URL routing — maps URL patterns to views | `api-handler`, `routing` |
|
||||
| `*/views.py`, `*/views/*.py` | Request handlers (function-based or class-based views) | `api-handler`, `controller` |
|
||||
| `*/models.py`, `*/models/*.py` | ORM models — map to database tables | `data-model` |
|
||||
| `*/serializers.py` | DRF serializers — convert models to/from JSON | `serialization`, `api-handler` |
|
||||
| `*/forms.py` | Django forms — validation and rendering logic | `validation`, `ui` |
|
||||
| `*/admin.py` | Admin site registrations — exposes models in Django admin | `config` |
|
||||
| `*/signals.py` | Signal handlers — cross-cutting side effects on model events | `event-handler` |
|
||||
| `*/tasks.py` | Celery async task definitions | `service`, `event-handler` |
|
||||
| `*/middleware.py`, `*/middleware/*.py` | Request/response middleware classes | `middleware` |
|
||||
| `*/permissions.py` | DRF permission classes | `middleware`, `validation` |
|
||||
| `*/filters.py` | DRF filter backends | `utility` |
|
||||
| `*/migrations/*.py` | Auto-generated schema migrations — do not summarize individually | `config` |
|
||||
| `*/templates/**/*.html` | Django HTML templates | `ui` |
|
||||
| `*/templatetags/*.py` | Custom template filters and tags | `utility` |
|
||||
| `*/management/commands/*.py` | Custom management commands (`./manage.py mycommand`) | `config`, `entry-point` |
|
||||
| `wsgi.py`, `asgi.py` | WSGI/ASGI server adapter — production entry point | `config`, `entry-point` |
|
||||
| `*/apps.py` | App configuration and startup hooks (`AppConfig`) | `config` |
|
||||
| `*/tests.py`, `*/tests/*.py` | Unit and integration tests | `test` |
|
||||
|
||||
### Edge Patterns to Look For
|
||||
|
||||
**URL routing graph** — Create `calls` edges from `urls.py` nodes to their corresponding view nodes when `path()` or `re_path()` maps a URL pattern to a view function or class. These edges represent the HTTP routing chain.
|
||||
|
||||
**Signal wiring** — When `signals.py` uses `post_save.connect(handler, sender=Model)` or `@receiver(post_save, sender=Model)`, create `subscribes` edges from the signal handler function to the model class. Create `publishes` edges from the model to the signal handler to show the trigger direction.
|
||||
|
||||
**ORM relationships** — When `models.py` defines `ForeignKey`, `OneToOneField`, or `ManyToManyField`, create `relates_to` edges (use `depends_on` edge type) between the model classes with a description indicating the relationship type and cardinality.
|
||||
|
||||
**Serializer-to-model binding** — When a DRF serializer has `model = MyModel` in its `Meta` class, create a `depends_on` edge from the serializer to the model.
|
||||
|
||||
**View-to-serializer binding** — When a DRF ViewSet or APIView references a serializer class, create a `depends_on` edge from the view to the serializer.
|
||||
|
||||
### Architectural Layers for Django
|
||||
|
||||
Assign nodes to these layers when detected:
|
||||
|
||||
| Layer ID | Layer Name | What Goes Here |
|
||||
|---|---|---|
|
||||
| `layer:api` | API Layer | `views.py`, `serializers.py`, `urls.py`, DRF ViewSets and APIViews |
|
||||
| `layer:data` | Data Layer | `models.py`, `migrations/`, database utility files |
|
||||
| `layer:service` | Service Layer | `signals.py`, `tasks.py`, custom managers, service modules |
|
||||
| `layer:ui` | UI Layer | `templates/`, `forms.py`, `templatetags/` |
|
||||
| `layer:middleware` | Middleware Layer | `middleware.py`, `permissions.py`, authentication backends |
|
||||
| `layer:config` | Config Layer | `settings.py`, `urls.py` (root), `wsgi.py`, `asgi.py`, `apps.py`, `manage.py` |
|
||||
| `layer:test` | Test Layer | `tests.py`, `tests/` directory, `conftest.py` |
|
||||
|
||||
### Notable Patterns to Capture in languageLesson
|
||||
|
||||
- **Fat models vs. thin views**: Django encourages business logic in model methods, keeping views thin HTTP adapters
|
||||
- **Django ORM lazy evaluation**: QuerySets are not evaluated until iterated — chain filters without DB hits
|
||||
- **Class-based views (CBVs)**: Mixins like `LoginRequiredMixin`, `PermissionRequiredMixin` compose behavior through multiple inheritance
|
||||
- **Signal anti-patterns**: Signals create invisible coupling; a signal in `signals.py` may be triggered by a `save()` call anywhere in the codebase
|
||||
- **App isolation**: Each Django app (`INSTALLED_APPS`) should be self-contained with its own models, views, urls, and migrations
|
||||
@@ -0,0 +1,109 @@
|
||||
# FastAPI / Flask Framework Addendum
|
||||
|
||||
> Injected into file-analyzer and architecture-analyzer prompts when FastAPI or Flask is detected.
|
||||
> Do NOT use as a standalone prompt — always appended to the base prompt template.
|
||||
|
||||
## FastAPI Project Structure
|
||||
|
||||
When analyzing a FastAPI project, apply these additional conventions on top of the base analysis rules.
|
||||
|
||||
### Canonical File Roles — FastAPI
|
||||
|
||||
| File / Pattern | Role | Tags |
|
||||
|---|---|---|
|
||||
| `main.py`, `app.py` | Application factory — creates and configures the `FastAPI()` instance | `entry-point`, `config` |
|
||||
| `*/routers/*.py`, `*/api/*.py` | `APIRouter` modules — group related endpoints by domain | `api-handler`, `routing` |
|
||||
| `*/schemas.py`, `*/schemas/*.py` | Pydantic request/response models | `type-definition`, `serialization` |
|
||||
| `*/models.py`, `*/models/*.py` | SQLAlchemy ORM models or other DB models | `data-model` |
|
||||
| `*/dependencies.py`, `*/deps.py` | `Depends()` provider functions — shared logic injected into routes | `service`, `middleware` |
|
||||
| `*/crud.py`, `*/repository.py` | Database access layer — CRUD operations | `data-model`, `service` |
|
||||
| `*/database.py`, `*/db.py` | DB engine, session factory, connection management | `config`, `data-model` |
|
||||
| `*/config.py`, `*/settings.py` | `pydantic-settings` / `BaseSettings` config classes | `config` |
|
||||
| `*/middleware.py` | Starlette middleware classes | `middleware` |
|
||||
| `*/exceptions.py` | Custom exception classes and exception handlers | `utility` |
|
||||
| `*/security.py`, `*/auth.py` | Auth utilities — JWT decoding, password hashing, OAuth helpers | `service`, `middleware` |
|
||||
| `*/tasks.py` | Background tasks or Celery task definitions | `service`, `event-handler` |
|
||||
| `*/tests/*.py`, `test_*.py` | pytest test files | `test` |
|
||||
| `conftest.py` | pytest fixtures and test configuration | `test`, `config` |
|
||||
|
||||
### Edge Patterns to Look For — FastAPI
|
||||
|
||||
**Router inclusion chain** — When `app.include_router(some_router, prefix="/api")` appears in `main.py` or a router aggregator, create `imports` + `depends_on` edges from the main app file to each router module. This builds the URL hierarchy graph.
|
||||
|
||||
**Dependency injection tree** — When a route function or another `Depends()` provider imports and calls `Depends(some_function)`, create `depends_on` edges from the caller to the dependency provider. Trace these chains — they often span multiple files (e.g., route → auth dependency → DB session dependency).
|
||||
|
||||
**Pydantic model inheritance** — When a schema class inherits from another (e.g., `class UserCreate(UserBase)`), create `inherits` edges between the schema class nodes.
|
||||
|
||||
**ORM model relationships** — When SQLAlchemy models use `relationship()`, `ForeignKey`, create `depends_on` edges between the model classes.
|
||||
|
||||
**CRUD-to-model binding** — When a `crud.py` function takes a model type as an argument or directly references a model class, create `depends_on` edges from the CRUD file to the model file.
|
||||
|
||||
### Architectural Layers for FastAPI
|
||||
|
||||
| Layer ID | Layer Name | What Goes Here |
|
||||
|---|---|---|
|
||||
| `layer:api` | API Layer | Router files, endpoint functions with `@router.get/post/...` decorators |
|
||||
| `layer:types` | Types Layer | Pydantic schema files, request/response models |
|
||||
| `layer:service` | Service Layer | `dependencies.py`, `crud.py`, business logic modules |
|
||||
| `layer:data` | Data Layer | ORM models, `database.py`, migrations |
|
||||
| `layer:config` | Config Layer | `main.py` / `app.py` factory, `settings.py`, `config.py` |
|
||||
| `layer:middleware` | Middleware Layer | `middleware.py`, `security.py`, `auth.py`, exception handlers |
|
||||
| `layer:test` | Test Layer | `tests/`, `conftest.py` |
|
||||
|
||||
### Notable Patterns to Capture in languageLesson
|
||||
|
||||
- **Dependency injection as composition**: FastAPI's `Depends()` is a first-class DI system — a route can declare any number of dependencies, each of which can have their own dependencies, forming a tree resolved at request time
|
||||
- **Pydantic for validation**: Request bodies, query params, and path params are automatically validated by Pydantic — invalid input raises `422 Unprocessable Entity` before your code runs
|
||||
- **Async endpoints**: `async def` routes run in the event loop; `def` routes run in a threadpool — mixing them incorrectly can cause performance issues
|
||||
- **Path operation order**: FastAPI matches routes in declaration order; a catch-all route before a specific one will shadow it
|
||||
|
||||
---
|
||||
|
||||
## Flask Project Structure
|
||||
|
||||
When analyzing a Flask project, apply these additional conventions on top of the base analysis rules.
|
||||
|
||||
### Canonical File Roles — Flask
|
||||
|
||||
| File / Pattern | Role | Tags |
|
||||
|---|---|---|
|
||||
| `app.py`, `__init__.py` (in app package) | Application factory (`create_app()`) or direct `Flask(__name__)` instance | `entry-point`, `config` |
|
||||
| `run.py`, `wsgi.py` | Production/dev server entry point | `entry-point`, `config` |
|
||||
| `*/views.py`, `*/routes.py` | Route handler functions with `@app.route` or `@blueprint.route` | `api-handler`, `routing` |
|
||||
| `*/blueprints/*.py`, `*/api/*.py` | Blueprint modules — group routes by feature | `api-handler`, `routing` |
|
||||
| `*/models.py` | SQLAlchemy models or other ORM models | `data-model` |
|
||||
| `*/forms.py` | WTForms form classes | `validation`, `ui` |
|
||||
| `*/schemas.py` | Marshmallow serialization schemas | `serialization`, `type-definition` |
|
||||
| `*/config.py` | Config classes (`DevelopmentConfig`, `ProductionConfig`) | `config` |
|
||||
| `*/extensions.py` | Flask extension initialization (`db = SQLAlchemy()`, `login_manager = LoginManager()`) | `config`, `singleton` |
|
||||
| `*/decorators.py` | Custom route decorators (auth guards, rate limiting) | `middleware`, `utility` |
|
||||
| `*/utils.py`, `*/helpers.py` | Shared utility functions | `utility` |
|
||||
| `*/templates/**/*.html` | Jinja2 templates | `ui` |
|
||||
| `*/static/` | CSS, JS, and asset files | `assets` |
|
||||
| `*/tests/*.py`, `test_*.py` | pytest or unittest test files | `test` |
|
||||
|
||||
### Edge Patterns to Look For — Flask
|
||||
|
||||
**Blueprint registration** — When `app.register_blueprint(bp, url_prefix='/api')` appears in the application factory, create `depends_on` edges from the app factory to each blueprint module.
|
||||
|
||||
**Extension coupling** — When a view imports from `extensions.py` (e.g., `from .extensions import db, login_manager`), create `imports` edges to show which views depend on which extensions.
|
||||
|
||||
**Before/after request hooks** — When `@app.before_request` or `@blueprint.before_request` decorates a function, create `middleware` edges from those functions to the app/blueprint they attach to.
|
||||
|
||||
### Architectural Layers for Flask
|
||||
|
||||
| Layer ID | Layer Name | What Goes Here |
|
||||
|---|---|---|
|
||||
| `layer:api` | API Layer | Blueprint route files, view functions |
|
||||
| `layer:data` | Data Layer | `models.py`, database migration files |
|
||||
| `layer:service` | Service Layer | Business logic modules, `schemas.py`, service classes |
|
||||
| `layer:ui` | UI Layer | `templates/`, `forms.py`, `static/` |
|
||||
| `layer:config` | Config Layer | `app.py` factory, `config.py`, `extensions.py` |
|
||||
| `layer:middleware` | Middleware Layer | `decorators.py`, before/after request hooks |
|
||||
| `layer:test` | Test Layer | Test files, `conftest.py` |
|
||||
|
||||
### Notable Patterns to Capture in languageLesson
|
||||
|
||||
- **Application factory pattern**: `create_app()` functions allow multiple app instances (e.g., for testing) and delay extension initialization — avoids circular imports
|
||||
- **Blueprint modularity**: Blueprints group related routes, templates, and static files; they are registered on the app with a URL prefix, making them independently testable
|
||||
- **Flask extension protocol**: Extensions follow `init_app(app)` for lazy initialization — the extension object is created globally but bound to an app instance later
|
||||
@@ -125,7 +125,10 @@ ENDJSON
|
||||
After writing the script, execute it. **Use the batch index in every temp file path** — multiple file-analyzer agents run in parallel and must not overwrite each other's files:
|
||||
|
||||
```bash
|
||||
# For Node.js scripts:
|
||||
node /tmp/ua-file-extract-<batchIndex>.js /tmp/ua-file-analyzer-input-<batchIndex>.json /tmp/ua-file-extract-results-<batchIndex>.json
|
||||
# For Python scripts:
|
||||
python3 /tmp/ua-file-extract-<batchIndex>.py /tmp/ua-file-analyzer-input-<batchIndex>.json /tmp/ua-file-extract-results-<batchIndex>.json
|
||||
```
|
||||
|
||||
If the script exits with a non-zero code, read stderr, diagnose the issue, fix the script, and re-run. You have up to 2 retry attempts.
|
||||
@@ -166,7 +169,9 @@ Indicators from script data:
|
||||
- Filename contains `.test.` or `.spec.` = `test`
|
||||
- Exports a class with `Handler` or `Controller` in the name = `api-handler`
|
||||
- Only type/interface exports = `type-definition`
|
||||
- Named `index.ts` at a directory root with re-exports = `entry-point`
|
||||
- Named `index.ts` or `index.js` at a directory root with re-exports = `entry-point` (JavaScript/TypeScript barrel)
|
||||
- Named `__init__.py` at a package root with imports or re-exports = `entry-point` (Python package barrel)
|
||||
- Named `manage.py` = `entry-point` (Django management script)
|
||||
|
||||
**Language Notes** (optional, your expert judgment):
|
||||
If the structural data reveals notable language-specific patterns (e.g., many generic type parameters, decorator usage, complex trait bounds), add a brief `languageNotes` string. Only add this when genuinely educational.
|
||||
|
||||
@@ -81,7 +81,9 @@ Read config files (if they exist) and extract framework information:
|
||||
- `tsconfig.json` -- if present, confirms TypeScript usage
|
||||
- `Cargo.toml` -- if present, confirms Rust project; extract `[package].name`
|
||||
- `go.mod` -- if present, confirms Go project; extract module name
|
||||
- `requirements.txt` / `pyproject.toml` / `setup.py` / `Pipfile` -- if present, confirms Python project
|
||||
- `requirements.txt` -- if present, confirms Python project; read line by line and match package names (strip version specifiers) against known Python frameworks: `django`, `djangorestframework`, `fastapi`, `flask`, `sqlalchemy`, `alembic`, `celery`, `pydantic`, `uvicorn`, `gunicorn`, `aiohttp`, `tornado`, `starlette`, `pytest`, `hypothesis`, `channels`
|
||||
- `pyproject.toml` -- if present, confirms Python project; parse the `[project].dependencies` or `[tool.poetry.dependencies]` section and apply the same Python framework keyword matching as above. Also check for `[tool.pytest.ini_options]` (confirms pytest) and `[tool.django]` (confirms Django).
|
||||
- `setup.py` / `setup.cfg` / `Pipfile` -- if present, confirms Python project; read and apply Python framework keyword matching
|
||||
- `Gemfile` -- if present, confirms Ruby project
|
||||
- `pom.xml` / `build.gradle` -- if present, confirms Java project
|
||||
|
||||
@@ -99,7 +101,8 @@ Extract from (in priority order):
|
||||
1. `package.json` `name` field
|
||||
2. `Cargo.toml` `[package].name`
|
||||
3. `go.mod` module path (last segment)
|
||||
4. Directory name of project root
|
||||
4. `pyproject.toml` -- check `[project].name` first, then `[tool.poetry].name`
|
||||
5. Directory name of project root
|
||||
|
||||
### Script Output Format
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ For every node, count how many other nodes it has edges pointing TO (fan-out). H
|
||||
**C. Entry Point Candidates**
|
||||
|
||||
Identify likely entry points using these signals (score each file node, sum the scores):
|
||||
- Filename matches `index.ts`, `index.js`, `main.ts`, `main.js`, `app.ts`, `app.js`, `server.ts`, `server.js`, `mod.rs`, `main.go`, `main.py`, `main.rs` -> +3 points
|
||||
- Filename matches `index.ts`, `index.js`, `main.ts`, `main.js`, `app.ts`, `app.js`, `server.ts`, `server.js`, `mod.rs`, `main.go`, `main.py`, `main.rs`, `manage.py`, `app.py`, `wsgi.py`, `asgi.py`, `run.py`, `__main__.py` -> +3 points
|
||||
- Node tags contain `entry-point` or `barrel` -> +2 points
|
||||
- File is at the project root or one level deep (e.g., `src/index.ts`) -> +1 point
|
||||
- High fan-out (top 10%) -> +1 point
|
||||
|
||||
Reference in New Issue
Block a user