Metadata-Version: 2.4
Name: django-graphify
Version: 0.1.1
Summary: Zero-LLM knowledge graph for Django projects — models, views, URLs, signals, serializers and more.
Author-email: Yogesh Chauhan <info.yogesh2848@gmail.com>
License: MIT
Project-URL: Repository, https://github.com/yogesh-chauhan-ai/django-graphify
Project-URL: Issues, https://github.com/yogesh-chauhan-ai/django-graphify/issues
Keywords: django,knowledge-graph,graph,visualization,static-analysis,ast,models,views,urls
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
Classifier: Framework :: Django :: 4.1
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Documentation
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django>=3.2
Requires-Dist: networkx>=3.0
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pytest-django>=4; extra == "dev"
Dynamic: license-file

# django-graphify

> Zero-LLM knowledge graph for Django projects.  
> Inspect models, views, URLs, signals, serializers, admin classes, middleware and settings — all fully offline.

[![PyPI](https://img.shields.io/pypi/v/django-graphify)](https://pypi.org/project/django-graphify/)
[![Python](https://img.shields.io/pypi/pyversions/django-graphify)](https://pypi.org/project/django-graphify/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

---

## Features

| Feature | Detail |
|---|---|
| **Zero LLM** | No API keys, no internet required at runtime |
| **Two-pass extraction** | AST (always works) + Django introspection (richer data) |
| **5 output formats** | `graph.json`, `graph.html`, `GRAPH_REPORT.md`, `graph.cypher`, `graph.mermaid` |
| **Interactive HTML** | Force-directed graph, D3 v7 bundled inline — fully offline |
| **All node types** | Models, Fields, Views (CBV+FBV), URLs, Signals, Serializers, Admin, Middleware, Settings, Apps |
| **Rich edges** | FK, M2M, OneToOne, URL→View, View→Model, View→Serializer, Signal, Admin, App dependency |
| **DRF support** | Auto-detected if `djangorestframework` is installed |
| **Single command** | `python manage.py graphify` |

---

## Installation

```bash
pip install django-graphify
```

Add to `INSTALLED_APPS`:

```python
INSTALLED_APPS = [
    ...
    "django_graphify",
]
```

---

## Quick start

```bash
# Full project graph — all formats
python manage.py graphify

# Single app
python manage.py graphify --app orders

# Custom output dir
python manage.py graphify --out ./docs/graph

# Only json + html
python manage.py graphify --format json html

# Cleaner graph — skip field-level nodes
python manage.py graphify --no-fields

# Only EXTRACTED edges (skip inferred queryset links)
python manage.py graphify --skip-inferred
```

Output lands in `./graphify-out/` by default:

```
graphify-out/
├── graph.html         ← interactive force-directed graph (open in browser)
├── graph.json         ← queryable node/edge data
├── GRAPH_REPORT.md    ← god nodes, URL chains, signal wiring, orphans
├── graph.cypher       ← Neo4j import
└── graph.mermaid      ← Mermaid flowchart (paste into any renderer)
```

---

## Command reference

| Option | Default | Description |
|---|---|---|
| `--app APP_LABEL` | all apps | Restrict to one Django app |
| `--out DIR` | `./graphify-out` | Output directory |
| `--format FMT …` | `all` | `json` `html` `md` `cypher` `mermaid` |
| `--no-fields` | off | Exclude field-level nodes |
| `--skip-inferred` | off | Only EXTRACTED edges |
| `--no-offline` | off | Use CDN for D3 instead of bundling |

---

## Node types

| Type | What it represents | Color |
|---|---|---|
| `model` | `models.Model` subclass | teal `#1D9E75` |
| `field` | Individual model field | light teal |
| `view` | CBV or FBV | purple `#534AB7` |
| `url` | `path()` / `re_path()` route | coral `#D85A30` |
| `signal` | Signal sender or receiver | pink `#D4537E` |
| `serializer` | DRF `Serializer` subclass | amber `#BA7517` |
| `admin` | `ModelAdmin` class | gray |
| `middleware` | Entry in `MIDDLEWARE` setting | blue `#378ADD` |
| `app` | Entry in `INSTALLED_APPS` | green `#639922` |
| `setting` | Top-level settings key | dark gray |

---

## Edge types

| Relation | Example | Tag |
|---|---|---|
| `fk` | `Order.customer → User` | EXTRACTED |
| `m2m` | `Post.tags → Tag` | EXTRACTED |
| `one_to_one` | `Profile.user → User` | EXTRACTED |
| `url_to_view` | `/api/orders/` → `OrderListView` | EXTRACTED |
| `view_to_model` | `OrderListView → Order` | INFERRED |
| `view_to_serializer` | `OrderListView → OrderSerializer` | EXTRACTED |
| `serializer_to_model` | `OrderSerializer → Order` | EXTRACTED |
| `signal_sender_receiver` | `post_save → send_welcome_email` | EXTRACTED |
| `admin_to_model` | `UserAdmin → User` | EXTRACTED |
| `app_dependency` | INSTALLED_APPS order | EXTRACTED |
| `model_has_field` | `Order → Order.status` | EXTRACTED |

Every edge is tagged `EXTRACTED` (found in source), `INFERRED` (confident guess), or `AMBIGUOUS` (needs review). INFERRED edges carry a `confidence` score (0–1).

---

## Python API

You can also drive extraction programmatically:

```python
from pathlib import Path
from django_graphify.graph import GraphBuilder
from django_graphify.extractors import ModelExtractor, ViewExtractor
from django_graphify.exporters import JsonExporter, HtmlExporter

builder = GraphBuilder(project_name="myproject")
root = Path("/path/to/project")

for ExtractorClass in [ModelExtractor, ViewExtractor]:
    extractor = ExtractorClass(root)
    nodes, edges = extractor.ast_extract()
    builder.add_nodes(nodes)
    builder.add_edges(edges)
    nodes, edges = extractor.introspect()
    builder.add_nodes(nodes)
    builder.add_edges(edges)

JsonExporter(builder).export(Path("./out"))
HtmlExporter(builder).export(Path("./out"))

# Query
node = builder.get_node("orders.Order")
neighbours = builder.get_neighbours("orders.Order")
path = builder.shortest_path("orders.Order", "users.User")
gods = builder.god_nodes(top_n=5)
orphans = builder.orphan_nodes()
```

---

## graph.json schema

```json
{
  "meta": {
    "project": "myproject",
    "django_version": "4.2.7",
    "generated_at": "2025-04-29T10:00:00Z",
    "node_count": 142,
    "edge_count": 89
  },
  "nodes": [
    {
      "id": "orders.Order",
      "type": "model",
      "label": "Order",
      "app": "orders",
      "file": "orders/models.py",
      "line": 14,
      "tag": "EXTRACTED",
      "confidence": 1.0,
      "meta": { "db_table": "orders_order", "abstract": false }
    }
  ],
  "edges": [
    {
      "source": "orders.Order",
      "target": "users.User",
      "relation": "fk",
      "tag": "EXTRACTED",
      "confidence": 1.0,
      "meta": { "field": "customer" }
    }
  ]
}
```

---

## How it works

**Pass 1 — AST (always runs):**  
Uses Python's `ast` module to walk every `.py` file. No Django import required. Extracts class names, base classes, field assignments, decorators. Works even if the project can't be fully imported.

**Pass 2 — Django introspection (runs when Django is configured):**  
Uses `django.apps.apps.get_models()`, `django.conf.settings`, and DRF's serializer registry to enrich Pass 1 nodes with concrete field types, FK targets, choices, `related_name`, middleware ordering, and installed app paths. Gracefully skipped if `DJANGO_SETTINGS_MODULE` isn't set.

---

## Requirements

- Python 3.10+
- Django 3.2+
- `networkx >= 3.0`
- `djangorestframework` (optional — DRF extraction auto-detected)

---

## Author

**Yogesh Chauhan** — AI and Django engineer, India.

[GitHub](https://github.com/yogesh-chauhan-ai) |
[LinkedIn](https://linkedin.com/in/yogesh-python-ai) |
[Portfolio](https://yogesh-python-ai.github.io)

---

## License

MIT — see [LICENSE](LICENSE).
