haider1998/pyvisualizer

GitHub: haider1998/pyvisualizer

基于 AST 静态分析的确定性 Python 调用图生成工具,提供架构可视化、CI 门禁和 AI 上下文精简能力。

Stars: 4 | Forks: 0

# 🗺️ py-code-visualizer [![PyPI](https://img.shields.io/pypi/v/py-code-visualizer.svg?color=7c3aed&label=py-code-visualizer)](https://pypi.org/project/py-code-visualizer/) [![下载量](https://img.shields.io/pypi/dm/py-code-visualizer.svg?color=2f81f7)](https://pypi.org/project/py-code-visualizer/) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/1d/1d494e8e0d31b078d30d4187a990f06e7c891c9e4fc1b3499c6d8dedecded045.svg)](https://github.com/haider1998/PyVisualizer/actions/workflows/ci.yml) [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![架构:已验证](https://img.shields.io/badge/architecture-verified-3fb950.svg)](#architecture)

py-code-visualizer: pip install, then visualize your project into a self-contained interactive map

⚡ 在浏览器中实时体验 →  ·  拖入 .py 文件,查看图表,不上传任何内容

py-code-visualizer 通过静态分析读取你的 Python 源码(绝不导入或执行任何代码),并生成你可以信任的调用图:自我修复的 README 图表、PR 架构变更报告、阻止循环依赖的 CI 门禁,以及完全离线的交互式地图。由于输出是**确定性的**,它可以存在于你的 pipeline 中且永不漂移。 ``` pip install py-code-visualizer && py-code-visualizer visualize . ``` **这是为谁准备的?** 任何技术栈的 Python 开发者: [**Django**](https://haider1998.github.io/pyvisualizer/for/django.html)(真实的请求流,而不仅仅是 model schema) · [**FastAPI**](https://haider1998.github.io/pyvisualizer/for/fastapi.html)(每个路由的影响范围,async + decorators) · [**ML pipelines**](https://haider1998.github.io/pyvisualizer/for/ml-pipelines.html) (映射 pipeline,找出废弃的实验)。查看 [客观比较](https://haider1998.github.io/pyvisualizer/compare.html) 和 [实测数据](https://haider1998.github.io/pyvisualizer/facts.html)。 ## 为什么会有这个工具(以及为什么 LLM 做不到) 被要求为你的代码库绘制图表的 LLM,会生成它*预期*像你这样的代码库所应具有的架构——看似合理、充满自信,却存在微妙的错误。它会臆造出从未相互调用的模块之间的链接,悄悄丢弃不适合 context window 的内容,并且每次运行给出的答案都不同,因此你永远无法对其进行 diff 或将其放入 CI。 PyVisualizer 在构建上恰恰相反: | | LLM 图表 | PyVisualizer | |---|---|---| | **正确性** | 推断得出,经常产生幻觉 | 从 AST 解析得出 | | **来源** | 无 | 每条边 → `file:line` | | **确定性** | 每次运行结果不同 | 字节完全一致 | | **歧义性** | 隐藏在自信的背后 | 被标记,并保留候选项 | | **可接入 CI** | 否 | 是 —— 门禁、diff、漂移检查 | | **代码是否离开本机** | 通常会 | 绝不 | 当一个调用确实无法解析为一个目标时,我们**不会随意选一个并假装如此**——我们会将该边标记为 `ambiguous` 并保留完整的候选列表。这种诚实正是产品的全部价值。 ## 安装 ``` pip install py-code-visualizer ``` ## 60秒入门 ``` # 交互式、完全独立的 HTML 地图(可离线打开,零网络) py-code-visualizer visualize ./your_project -o architecture.html # 在您的 README 中永久保留实时图表 py-code-visualizer readme ./your_project # 出现新的 circular dependencies 时使 CI 失败 py-code-visualizer check ./your_project --fail-on-cycles # 如果我修改这个函数,什么会受到影响? py-code-visualizer impact your_pkg.core.save ./your_project ``` ## ⚡ AI agent context —— 减少 97% 的 token 与其将整个代码库粘贴到 Claude / ChatGPT / Cursor 中,不如给它真正重要且经过验证的 4,000-token 切片。三个命令涵盖所有工作流: ``` # 选项 A — 用 plain English 描述任务(无需 function name) py-code-visualizer context . --task "add retry logic to the HTTP client" --budget-tokens 4000 # 选项 B — 您知道该函数 py-code-visualizer context . --focus send_request --budget-tokens 4000 # 选项 C — 永久接入(agents 自动读取) py-code-visualizer export --for-ai . ``` **复制 A 或 B 的输出 → 粘贴到 AI 聊天中你的问题之前。** 现在 AI 拥有了正确的 context,而不是猜测出的 140,000 个 token。 | 方法 | Token | Claude Opus 5 成本 | 每 1k token 的信噪比 | |---|---|---|---| | 完整源码 | 139,697 | $2.10 | 1× | | Keyword grep | 24,652 | $0.37 | 6× | | **pyvisualizer `--task`** | **~4,000** | **$0.06** | **35×** | _基于 httpx(真实的开源项目,1,076 个函数)实测。参见 [实测数据](https://haider1998.github.io/pyvisualizer/use-cases/agent-context.html)。_ ## 适合拼搏的初创公司 🚀 你永远不会专门排期一个“文档冲刺”。所以别这么做。只需在 CI 中添加一行,你的 README 就会始终带有最新的架构图表——免费准备好供投资人和尽职_Due Diligence_查看——同时每个 PR 都会获得一条评论,准确显示结构上的变更。 ``` # .github/workflows/architecture.yml - uses: haider1998/PyVisualizer@v2 with: { mode: readme } ``` 新承包商通过交互式地图即可完成入职,而无需经历长达三天的 Slack 问答。项目转型不再是考古挖掘。 ## 适合世界 500 强企业 🏛️ - **代码绝不离开本机。** 纯 AST,无执行,无 API 调用——用于安全审查的终极反 LLM 工具。生成的 HTML 是一个单一文件,没有任何网络请求(物理隔离安全)。 - **架构即代码门禁。** 声明层级和禁止的依赖关系;违规时构建失败——在*调用图*层面操作,比 import linter 更严格。 - **审计追踪。** 由 CI 提交的确定性图表使 git 历史记录成为你带日期、可追溯的架构变更日志(SOC 2 / 审查委员会)。 - **Monorepo 规模。** 分层汇总(module → class → function),绝不进行静默采样。 ``` # pyproject.toml [tool.pyvisualizer.rules] layers = ["api", "domain", "infra"] forbid = ["domain -> api", "domain -> infra"] ``` ## 命令 | 命令 | 功能说明 | |---|---| | `review --base ` | **PR 审查报告**:变更的函数、影响范围、风险标记、聚焦的子图——每个引用均可点击 `file:line` | | `context --focus ` | **为 AI agent 验证过的 context pack**:任务作用域、预算受限、零猜测边 | | `context --task ""` | 相同的 pack,由**自然语言任务描述**作为种子(优先匹配命名符号,将词汇匹配作为带标签的提示;`--strategy graph\|text\|hybrid`) | | `visualize` | 渲染 `html` · `mermaid` · `json` · `c4` · `svg`/`png` | | `readme` | 在任何 Markdown 文件中注入/更新 Mermaid 图表(幂等)+ 跳转到源码索引 | | `json` | 输出规范的、可 diff 的图表 JSON | | `diff base.json head.json` | 可直接用于 PR 的架构变更报告(+ 新循环门禁) | | `check` | 强制执行层级规则和循环检查——CI 门禁(也支持 `--dead-code`) | | `impact ` | 影响范围:传递性调用者/被调用者 + 风险说明行(`--format markdown`) | | `health` | 架构健康评分(A–F),附带 SVG 徽章 | | `export` | `ARCHITECTURE.json` + `ARCHITECTURE.md` + AGENTS.md 接线配置(`--check` 新鲜度门禁) | | `init` | 自愿参与的设置——仅生成你选择的自动化(`review`/`readme`/`context`/`gates`) | **两个任务,一个引擎。** *review* 让大型代码库上的代码审查变成只需几分钟的聚焦过程;*context* 为 AI agent 提供架构中经过验证、**小了 97%** 的切片,而不是整个代码库。参见 [`VISION.md`](VISION.md) 和[用例演练](https://haider1998.github.io/pyvisualizer/use-cases/)。 ### MCP server(实时、任务中) 如果你使用 Claude Code 或 Cursor,MCP server 允许 agent 在需要时查询验证过的图表——无需手动复制粘贴: ``` pip install 'py-code-visualizer[mcp]' # Python 3.10+ pyvisualizer-mcp /path/to/project ``` 添加到 `.mcp.json` 后,三个工具即可使用:`search_code`、`context_pack` 和 `impact`。该 server 仅在文件更改时重新构建。 完整使用指南(所有 flag、故障排除、输出说明):**[AI_CONTEXT.md](AI_CONTEXT.md)** ## 用例(真实命令、真实输出) 三个端到端的演练,每个都由 [`examples/scenarios/`](examples/scenarios) 中可运行的 fixture 提供支持——每个命令和每一行输出都是可复现的,没有任何虚假演示: - 🗺️ **[孤立的巨石应用](https://haider1998.github.io/pyvisualizer/use-cases/orphan-monolith.html)** — 通过 `visualize` + `health` + `check --dead-code` 入职未文档化的代码库。 - 🛡️ **[审计截止日期](https://haider1998.github.io/pyvisualizer/use-cases/soc2-audit.html)** — 在调用图级别强制执行层级规则,并生成带日期的 SOC 2 证据。 - 🧨 **[无所畏惧的重构](https://haider1998.github.io/pyvisualizer/use-cases/fearless-refactor.html)** — `impact` 影响范围分析,随后是导致 PR 在出现新循环时失败的 `diff` 门禁。 查看[完整的用例索引 + 每个命令的配方](https://haider1998.github.io/pyvisualizer/use-cases/)。 **实测数据**(可通过 `python benchmarks/bench.py` → [`docs/benchmarks.json`](docs/benchmarks.json) 复现): 一个 **98,669 行**的项目可在 **~4.9 秒**内映射为完整的调用图(26,658 个函数),**100%** 的边都带有 `file:line`,输出在不同运行之间是**字节完全一致**的,并且生成的 HTML 会发起 **0** 次网络请求。*(macOS arm64,Python 3.14;速度取决于硬件——溯源性、确定性和零网络是结构性的。)* ## 交互式地图 一个单一的自包含 HTML 文件(无 CDN,离线可用): - **分层抽象** —— 切换 module → class → function 视图 - **点击任意节点** —— 签名、`file:line`、调用者和被调用者(均可点击) - **⌘K 命令面板**、实时搜索、module 过滤器 - **深度链接** —— URL 编码了选中的节点;将其粘贴到 Slack,你的团队成员就能直接定位到确切的函数 - **导览模式** —— 从检测到的入口点自动生成演示 - **叠加层** —— 循环(红色)、歧义(虚线)和 `--churn` git 热力图 - 缩略图、平移/缩放/拖拽、明亮/深色模式、SVG 导出 ## 将图表喂给你的 AI 工具 ``` py-code-visualizer export --for-ai ./your_project ``` 让 Cursor / Claude 指向经过验证的 `ARCHITECTURE.json`,而不是让模型从原始源码中重新推导结构。**让你的 agent 指向图表,而不是代码库。** ## 准确性保证 - 嵌套的 class、method 和 closure 在被收集时带有正确的限定名称(`pkg.Outer.Inner.method`、`mod.func..inner`)。 - 链式调用(`get_client().fetch()`)、comprehensions 和 lambdas 均被捕获。 - `super()`/继承的调用通过计算出的 MRO 解析(标记为 `inherited`)。 - 参数和变量类型注解驱动 method 解析。 - 对 stdlib/第三方代码的调用**不会产生边** —— 我们绝不臆造。 - 歧义调用会被标记并作为候选项保留;`--strict` 会丢弃它们。 关于 GitHub Actions、GitLab CI 和 pre-commit 设置,请参见 [`docs/integrations.md`](docs/integrations.md)。 ## 配置 ``` [tool.pyvisualizer] exclude = ["tests", "migrations"] max_nodes = 120 target = "README.md" detail = "module" # module | class | function ``` ## 路线图 - ⏳ **时光旅行** —— 在各个版本中穿梭浏览你架构的演进 - 🔁 **Watch 模式** —— 在你重构时实时重载地图 - ✅ ~~**MCP server**~~ —— 已发布:`pyvisualizer-mcp`(`search_code`、`context_pack`、`impact`) ## 架构 下面的图表由 PyVisualizer 自身生成,并由 CI 保持同步。 *120 个函数 · 214 次调用 · 健康 F (46/100) — 详情:module* ``` flowchart LR g0["bench"] g1["genproject"] g2["main"] g3["models"] g4["services"] g5["urls"] g6["repos"] g7["services"] g8["evaluate"] g9["features"] g10["ingest"] g11["pipeline"] g12["train"] g13["cli"] g14["pipeline"] g15["transforms"] g16["core"] g17["service"] g18["billing"] g19["api"] g20["changes"] g21["cli"] g22["config"] g23["context"] g24["analyzer"] g25["graph"] g26["diff"] g27["export"] g28["gates"] g29["impact"] g30["inject"] g31["mcp_server"] g32["metrics"] g33["overlays"] g34["retrieval"] g35["review"] g36["c4"] g37["json_graph"] g38["setup_init"] g39["file_discovery"] g40["d3"] g41["html"] g42["mermaid"] g0 --> g1 g0 --> g19 g0 --> g37 g0 --> g41 g1 --> g6 g4 --> g3 g7 -.-> g4 g7 --> g6 g11 --> g8 g11 --> g9 g11 --> g10 g11 --> g12 g13 --> g14 g14 -.-> g7 g14 --> g15 g15 -.-> g4 g17 --> g16 g19 --> g25 g19 --> g31 g19 --> g39 g20 --> g31 g20 --> g33 g21 --> g14 g21 --> g19 g21 --> g22 g21 --> g23 g21 --> g26 g21 --> g27 g21 --> g28 g21 --> g29 g21 --> g30 g21 --> g31 g21 --> g32 g21 --> g33 g21 --> g35 g21 --> g36 g21 --> g37 g21 --> g40 g21 --> g42 g22 --> g31 g23 --> g4 g23 --> g20 g23 --> g28 g23 --> g29 g23 --> g31 g23 --> g32 g23 --> g33 g23 --> g34 g24 --> g31 g25 --> g4 g25 --> g31 g26 --> g4 g26 --> g31 g26 --> g32 g27 --> g28 g27 --> g30 g27 --> g31 g27 --> g32 g27 --> g37 g28 --> g31 g29 --> g20 g31 --> g19 g31 --> g23 g31 --> g29 g31 --> g34 g32 --> g31 g32 --> g34 g33 --> g31 g34 --> g4 g34 --> g31 g35 --> g20 g35 --> g28 g35 --> g31 g35 --> g32 g35 --> g42 g36 --> g42 g37 --> g31 g38 --> g19 g38 --> g30 g38 --> g31 g38 --> g32 g38 --> g42 g39 --> g4 g39 --> g6 g40 --> g41 g41 --> g37 g42 --> g31 ``` 🔒 确定性、经过 AST 验证 —— 未执行任何代码。由 [py-code-visualizer](https://github.com/haider1998/PyVisualizer) 生成。
📍 跳转到源码(120 个函数) - [`benchmarks.bench._bench_target`](benchmarks/bench.py#L177) - [`benchmarks.bench._determinism_proof`](benchmarks/bench.py#L113) - [`benchmarks.bench._html_network_proof`](benchmarks/bench.py#L132) - [`benchmarks.bench.run`](benchmarks/bench.py#L221) - [`benchmarks.genproject._gen_module`](_URL_27/>) - [`benchmarks.genproject.generate`](benchmarks/genproject.py#L135) - [`examples.sample_project.main.main`](examples/sample_project/main.py#L7) - [`examples.scenarios.django_shop.models.Cart.for_user`](examples/scenarios/django_shop/models.py#L12) - [`examples.scenarios.django_shop.services.CartService.add`](examples/scenarios/django_shop/services.py#L11) - [`examples.scenarios.django_shop.services.OrderService.checkout`](examples/scenarios/django_shop/services.py#L22) - [`examples.scenarios.django_shop.services.OrderService.get`](examples/scenarios/django_shop/services.py#L29) - [`examples.scenarios.django_shop.urls.dispatch`](examples/scenarios/django_shop/urls.py#L7) - [`examples.scenarios.fastapi_svc.repos.OrderRepo.insert`](examples/scenarios/fastapi_svc/repos.py#L8) - [`examples.scenarios.fastapi_svc.services.OrderFlow.fetch`](examples/scenarios/fastapi_svc/services.py#L22) - [`examples.scenarios.fastapi_svc.services.OrderFlow.place`](examples/scenarios/fastapi_svc/services.py#L16) - [`examples.scenarios.ml_pipeline.evaluate.evaluate_model`](examples/scenarios/ml_pipeline/evaluate.py#L4) - [`examples.scenarios.ml_pipeline.features.build_features`](examples/scenarios/ml_pipeline/features.py#L4) - [`examples.scenarios.ml_pipeline.ingest.load_dataset`](examples/scenarios/ml_pipeline/ingest.py#L4) - [`examples.scenarios.ml_pipeline.pipeline.run`](examples/scenarios/ml_pipeline/pipeline.py#L9) - [`examples.scenarios.ml_pipeline.train.train_model`](examples/scenarios/ml_pipeline/train.py#L4) - [`examples.scenarios.orphan_monolith.app.cli.run`](examples/scenarios/orphan_monolith/app/cli.py#L7) - [`examples.scenarios.orphan_monolith.app.pipeline.ReportPipeline.build`](examples/scenarios/orphan_monolith/app/pipeline.py#L11) - [`examples.scenarios.orphan_monolith.app.pipeline.ReportPipeline.render`](examples/scenarios/orphan_monolith/app/pipeline.py#L16) - [`examples.scenarios.orphan_monolith.app.transforms.summarize`](examples/scenarios/orphan_monolith/app/transforms.py#L11) - [`examples.scenarios.refactor.after.core.persist`](examples/scenarios/refactor/after/core.py#L7) - [`examples.scenarios.refactor.after.service.cancel_order`](examples/scenarios/refactor/after/service.py#L11) - [`examples.scenarios.refactor.after.service.place_order`](examples/scenarios/refactor/after/service.py#L7) - [`examples.scenarios.soc2_audit.domain.billing.BillingService.charge`](examples/scenarios/soc2_audit/domain/billing.py#L12) - [`pyvisualizer.api.build_graph`](pyvisualizer/api.py#L47) - [`pyvisualizer.changes.Linker.ref`](pyvisualizer/changes.py#L202) - [`pyvisualizer.changes.changed_lines_from_git`](pyvisualizer/changes.py#L62) - [`pyvisualizer.changes.map_lines_to_functions`](pyvisualizer/changes.py#L121) - [`pyvisualizer.changes.repo_web_url`](pyvisualizer/changes.py#L149) - [`pyvisualizer.changes.resolve_base_ref`](pyvisualizer/changes.py#L46) - [`pyvisualizer.cli._build`](pyvisualizer/cli.py#L283) - [`pyvisualizer.cli._render_graphviz`](pyvisualizer/cli.py#L368) - [`pyvisualizer.cli.cmd_check`](pyvisualizer/cli.py#L588) - [`pyvisualizer.cli.cmd_context`](pyvisualizer/cli.py#L706) - [`pyvisualizer.cli.cmd_diff`](pyvisualizer/cli.py#L550) - [`pyvisualizer.cli.cmd_export`](pyvisualizer/cli.py#L647) - [`pyvisualizer.cli.cmd_health`](pyvisualizer/cli.py#L623) - [`pyvisualizer.cli.cmd_impact`](pyvisualizer/cli.py#L669) - [`pyvisualizer.cli.cmd_readme`](pyvisualizer/cli.py#L458) - [`pyvisualizer.cli.cmd_review`](pyvisualizer/cli.py#L681) - [`pyvisualizer.cli.cmd_visualize`](pyvisualizer/cli.py#L302) - [`pyvisualizer.cli.main`](pyvisualizer/cli.py#L264) - [`pyvisualizer.config.load_config`](pyvisualizer/config.py#L102) - [`pyvisualizer.context._est_tokens`](pyvisualizer/context.py#L135) - [`pyvisualizer.context._node_line`](pyvisualizer/context.py#L110) - [`pyvisualizer.context._resolve_focus`](pyvisualizer/context.py#L83) - [`pyvisualizer.context._select_nodes`](pyvisualizer/context.py#L246) - [`pyvisualizer.context._select_text`](pyvisualizer/context.py#L297) - [`pyvisualizer.context._upgrade_bodies`](pyvisualizer/context.py#L338) - [`pyvisualizer.context.build_context_pack`](pyvisualizer/context.py#L387) - [`pyvisualizer.core.analyzer.DefinitionCollector._visit_function`](pyvisualizer/core/analyzer.py#L360) - [`pyvisualizer.core.analyzer.DefinitionCollector.visit_ClassDef`](pyvisualizer/core/analyzer.py#L327) - [`pyvisualizer.core.analyzer.ModuleAnalyzer._decorator_names`](pyvisualizer/core/analyzer.py#L158) - [`pyvisualizer.core.analyzer.ModuleAnalyzer._extract_attribute_chain`](pyvisualizer/core/analyzer.py#L189) - [`pyvisualizer.core.analyzer.ModuleAnalyzer._process_annotation`](pyvisualizer/core/analyzer.py#L259) - [`pyvisualizer.core.analyzer.ModuleAnalyzer._process_decorator`](pyvisualizer/core/analyzer.py#L206) - [`pyvisualizer.core.graph.FunctionCallVisitor._extract_attribute_chain`](pyvisualizer/core/graph.py#L421) - [`pyvisualizer.core.graph.FunctionCallVisitor._extract_call_target`](pyvisualizer/core/graph.py#L407) - [`pyvisualizer.core.graph.FunctionCallVisitor._find_method_in_hierarchy`](pyvisualizer/core/graph.py#L329) - [`pyvisualizer.core.graph.FunctionCallVisitor._resolve_call`](pyvisualizer/core/graph.py#L201) - [`pyvisualizer.core.graph.FunctionCallVisitor._seed_param_types`](pyvisualizer/core/graph.py#L121) - [`pyvisualizer.core.graph.FunctionCallVisitor._visit_function_common`](pyvisualizer/core/graph.py#L96) - [`pyvisualizer.core.graph.build_call_graph`](pyvisualizer/core/graph.py#L475) - [`pyvisualizer.diff.diff_graphs`](pyvisualizer/diff.py#L84) - [`pyvisualizer.diff.render_change_mermaid`](pyvisualizer/diff.py#L131) - [`pyvisualizer.diff.render_markdown`](pyvisualizer/diff.py#L170) - [`pyvisualizer.export._agents_md_plan`](pyvisualizer/export.py#L154) - [`pyvisualizer.export._json_content`](pyvisualizer/export.py#L113) - [`pyvisualizer.export.build_ai_markdown`](pyvisualizer/export.py#L32) - [`pyvisualizer.export.export_for_ai`](pyvisualizer/export.py#L173) - [`pyvisualizer.export.export_would_change`](pyvisualizer/export.py#L199) - [`pyvisualizer.gates.check_layer_rules`](pyvisualizer/gates.py#L53) - [`pyvisualizer.gates.find_cycles`](pyvisualizer/gates.py#L83) - [`pyvisualizer.impact.analyze_impact`](pyvisualizer/impact.py#L46) - [`pyvisualizer.impact.render_markdown`](pyvisualizer/impact.py#L96) - [`pyvisualizer.impact.resolve_target`](pyvisualizer/impact.py#L32) - [`pyvisualizer.inject.inject`](pyvisualizer/inject.py#L84) - [`pyvisualizer.inject.inject_block`](pyvisualizer/inject.py#L51) - [`pyvisualizer.inject.update_file`](pyvisualizer/inject.py#L102) - [`pyvisualizer.mcp_server.ProjectSession.get`](pyvisualizer/mcp_server.py#L54) - [`pyvisualizer.mcp_server.tool_context_pack`](pyvisualizer/mcp_server.py#L82) - [`pyvisualizer.mcp_server.tool_impact`](pyvisualizer/mcp_server.py#L107) - [`pyvisualizer.metrics._is_entry_point`](pyvisualizer/metrics.py#L75) - [`pyvisualizer.metrics.compute_health`](pyvisualizer/metrics.py#L88) - [`pyvisualizer.metrics.find_dead_code`](pyvisualizer/metrics.py#L153) - [`pyvisualizer.overlays._git`](pyvisualizer/overlays.py#L23) - [`pyvisualizer.overlays._toplevel`](pyvisualizer/overlays.py#L33) - [`pyvisualizer.overlays.apply_churn`](pyvisualizer/overlays.py#L67) - [`pyvisualizer.overlays.git_churn`](pyvisualizer/overlays.py#L41) - [`pyvisualizer.retrieval.BM25Index.rank`](pyvisualizer/retrieval.py#L120) - [`pyvisualizer.retrieval.BM25Index.search`](pyvisualizer/retrieval.py#L137) - [`pyvisualizer.retrieval.build_bm25`](pyvisualizer/retrieval.py#L142) - [`pyvisualizer.retrieval.derive_seeds`](pyvisualizer/retrieval.py#L189) - [`pyvisualizer.retrieval.function_source`](pyvisualizer/retrieval.py#L75) - [`pyvisualizer.retrieval.rank_seeds`](pyvisualizer/retrieval.py#L219) - [`pyvisualizer.retrieval.tokenize`](pyvisualizer/retrieval.py#L64) - [`pyvisualizer.review._risk_lines`](pyvisualizer/review.py#L183) - [`pyvisualizer.review.analyze_review`](pyvisualizer/review.py#L50) - [`pyvisualizer.review.render_markdown`](pyvisualizer/review.py#L112) - [`pyvisualizer.review.render_text`](pyvisualizer/review.py#L198) - [`pyvisualizer.serializers.c4.generate_c4_dsl`](pyvisualizer/serializers/c4.py#L27) - [`pyvisualizer.serializers.json_graph.graph_to_dict`](pyvisualizer/serializers/json_graph.py#L65) - [`pyvisualizer.serializers.json_graph.graph_to_json`](pyvisualizer/serializers/json_graph.py#L162) - [`pyvisualizer.setup_init._action_readme`](pyvisualizer/setup_init.py#L232) - [`pyvisualizer.setup_init._record_features`](pyvisualizer/setup_init.py#L205) - [`pyvisualizer.setup_init.run_init`](pyvisualizer/setup_init.py#L305) - [`pyvisualizer.utils.file_discovery.analyze_project`](pyvisualizer/utils/file_discovery.py#L151) - [`pyvisualizer.utils.file_discovery.find_project_python_files`](pyvisualizer/utils/file_discovery.py#L38) - [`pyvisualizer.utils.file_discovery.get_module_name`](pyvisualizer/utils/file_discovery.py#L96) - [`pyvisualizer.visualizers.d3.generate_d3_visualization`](pyvisualizer/visualizers/d3.py#L18) - [`pyvisualizer.visualizers.html.generate_html_visualization`](pyvisualizer/visualizers/html.py#L29) - [`pyvisualizer.visualizers.mermaid._categorize_methods`](pyvisualizer/visualizers/mermaid.py#L301) - [`pyvisualizer.visualizers.mermaid._rollup`](pyvisualizer/visualizers/mermaid.py#L39) - [`pyvisualizer.visualizers.mermaid.create_interactive_html`](pyvisualizer/visualizers/mermaid.py#L336) - [`pyvisualizer.visualizers.mermaid.generate_github_mermaid`](pyvisualizer/visualizers/mermaid.py#L82) - [`pyvisualizer.visualizers.mermaid.generate_styled_mermaid`](pyvisualizer/visualizers/mermaid.py#L114)
## 贡献 请参见 [CONTRIBUTING.md](CONTRIBUTING.md)。PyVisualizer 采用 MIT 许可协议。 ## 作者 **Syed Mohd Haider Rizvi** [作品集](https://haider1998.github.io/) · [LinkedIn](https://www.linkedin.com/in/s-m-h-rizvi-0a40441ab/) · [GitHub](https://github.com/haider1998)
标签:Python, 云安全监控, 代码可视化, 多模态安全, 无后门, 自动化payload嵌入, 调用图, 逆向工具, 静态分析