File size: 3,027 Bytes
773e892
c98d640
 
1903343
 
 
a5f8603
c98d640
 
 
a908fc5
1903343
 
 
 
 
 
 
 
 
 
 
7a699a5
 
d48fa34
a62882f
 
 
 
 
 
 
82531de
d48fa34
643dcb7
1903343
 
a62882f
c98d640
957162f
d48fa34
12a0822
 
c98d640
cb4a67f
 
f9a6b46
 
 
957162f
773e892
12a0822
 
c98d640
957162f
2f387d0
12a0822
 
c98d640
12a0822
ed41156
12a0822
 
643dcb7
 
d48fa34
643dcb7
f9a6b46
 
cb4a67f
f9a6b46
 
 
ed41156
643dcb7
d48fa34
643dcb7
 
 
 
 
 
 
29ad70f
 
 
a62882f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import asyncio
import os

import streamlit as st
import streamlit.components.v1 as components

from py_code_analyzer import CodeFetcher, CodeImportsAnalyzer, ImportsGraphVisualizer
from utils import conditonal_decorator, time_function

DEV = int(os.environ.get("DEV", "1"))

TITLE = "Python Code Analyzer"
st.set_page_config(page_title=TITLE, layout="wide")
st.title(TITLE)
st.markdown(
    "The main purpose of the app is to allow Python developers navigate Python code base much "
    + "easier by showing dependencies among files included in the directory with better visualization."
)
st.markdown(
    "**Checkout the source code [here](https://github.com/cyyeh/py-code-analyzer)**"
)

owner = st.text_input("Fill in the GitHub username", value="cyyeh")
repo = st.text_input("Fill in the GitHib repository", value="py-code-analyzer")
tree_sha = st.text_input(
    "Fill in SHA", value="2f387d0adea72a7b4c99a5e8fc3e4fd83b5469b8"
)
show_graph_visualization = st.checkbox(
    "Show graph visualization",
    value=True,
    help="If the graph is large, then consider uncheck the checkbox. "
    "For example, the result graph of fetching TensorFlow repo would be large.",
)
clicked_ok_button = st.button("OK", disabled=not owner or not repo or not tree_sha)
st.markdown("---")


@st.cache
@conditonal_decorator(time_function, DEV)
def get_python_files(owner: str, repo: str, tree_sha: str):
    return CodeFetcher().get_python_files(owner, repo, tree_sha)


@conditonal_decorator(time_function, DEV)
def parse_python_files(analyzer: CodeImportsAnalyzer):
    asyncio.run(analyzer.parse_python_files())


@conditonal_decorator(time_function, DEV)
def generate_imports_graph(analyzer: CodeImportsAnalyzer):
    return analyzer.generate_imports_graph()


@conditonal_decorator(time_function, DEV)
def generate_graph_visualization_file(imports_graph, heading: str):
    ImportsGraphVisualizer().visualize(imports_graph, heading=heading)


@conditonal_decorator(time_function, DEV)
def read_graph_visualization_file():
    return open("nx.html", "r", encoding="utf-8").read()


if clicked_ok_button and owner and repo:
    with st.spinner("Getting python files..."):
        python_files = get_python_files(owner, repo, tree_sha)

    analyzer = CodeImportsAnalyzer(python_files)
    with st.spinner("Parsing python files..."):
        parse_python_files(analyzer)

    with st.spinner("Generating imports graph..."):
        imports_graph = generate_imports_graph(analyzer)

    with st.spinner("Generating graph visualization file..."):
        generate_graph_visualization_file(imports_graph, f"{owner}/{repo}")
        graph_visualization_file = read_graph_visualization_file()
        st.download_button(
            "Download the result file",
            graph_visualization_file,
            file_name="result.html",
            mime="text/html",
        )

    if show_graph_visualization:
        with st.spinner("Showing the graph..."):
            components.html(graph_visualization_file, height=600, scrolling=True)