파이썬 스크립트 파악할 때, 함수간 호출관계 및 파라미터 파악이 귀찮아서 파이썬 소스 기반 확인하는 스크립트 작성함.
파이썬 노트북에서 실행 가정하고 만듦.
소스코드
import ast
import networkx as nx
from pathlib import Path
import matplotlib.pyplot as plt
import pandas as pd
class CallGraphBuilder(ast.NodeVisitor):
def __init__(self):
self.graph = nx.DiGraph()
self.current_func = None
self.func_defs = {} # 함수 이름 → 파라미터 리스트
self.edges = [] # (caller, callee, Source_param, Target_param)
def visit_FunctionDef(self, node):
func_name = node.name
self.func_defs[func_name] = [arg.arg for arg in node.args.args]
prev = self.current_func
self.current_func = func_name
self.generic_visit(node)
self.current_func = prev
def visit_Call(self, node):
if self.current_func:
callee = self._get_func_name(node.func)
if callee and callee in self.func_defs: # 파일 내부 정의된 함수만 추적
arg_pairs = self._map_args(callee, node)
self.graph.add_edge(self.current_func, callee)
for target_param, source_expr in arg_pairs.items():
self.edges.append(
(self.current_func, callee, source_expr, target_param)
)
self.generic_visit(node)
def _get_func_name(self, node):
if isinstance(node, ast.Name):
return node.id
return None # Attribute 등은 무시
def _map_args(self, callee, node: ast.Call):
arg_map = {}
params = self.func_defs.get(callee, [])
# 위치 인자
for param, arg in zip(params, node.args):
arg_map[param] = self._expr_to_str(arg)
# 키워드 인자
for kw in node.keywords:
if kw.arg:
arg_map[kw.arg] = self._expr_to_str(kw.value)
return arg_map
def _expr_to_str(self, node):
try:
return ast.unparse(node) # Python 3.9+
except Exception:
return type(node).__name__
def build_call_graph(pyfile: str):
src = Path(pyfile).read_text(encoding="utf-8")
tree = ast.parse(src)
builder = CallGraphBuilder()
builder.visit(tree)
return builder.graph, builder.edges
def visualize_graph(G):
pos = nx.spring_layout(G, seed=42)
plt.figure(figsize=(12, 8))
nx.draw(
G, pos,
with_labels=True,
node_color="lightblue",
node_size=2000,
font_size=12,
font_weight="bold",
arrows=True
)
plt.show()
def edges_to_dataframe(edges):
return pd.DataFrame(edges, columns=["Source", "Target", "Source_param", "Target_param"])
# === 실행 예시 ===
graph, edges = build_call_graph("../langgraph/policy_api.py") # 분석할 .py 파일
visualize_graph(graph)
df = edges_to_dataframe(edges)[["Source", "Source_param", "Target_param", "Target"]].sort_values(['Source','Source_param'])
df
실행 예시
