methodgraph 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- methodgraph-0.1.0/LICENSE +20 -0
- methodgraph-0.1.0/MANIFEST.in +1 -0
- methodgraph-0.1.0/PKG-INFO +154 -0
- methodgraph-0.1.0/README.md +138 -0
- methodgraph-0.1.0/methodgraph/__init__.py +28 -0
- methodgraph-0.1.0/methodgraph/cli.py +79 -0
- methodgraph-0.1.0/methodgraph/collector.py +307 -0
- methodgraph-0.1.0/methodgraph/renderer.py +42 -0
- methodgraph-0.1.0/methodgraph/server.py +33 -0
- methodgraph-0.1.0/methodgraph/templates/report.html +2350 -0
- methodgraph-0.1.0/methodgraph/tracer.py +297 -0
- methodgraph-0.1.0/methodgraph.egg-info/PKG-INFO +154 -0
- methodgraph-0.1.0/methodgraph.egg-info/SOURCES.txt +17 -0
- methodgraph-0.1.0/methodgraph.egg-info/dependency_links.txt +1 -0
- methodgraph-0.1.0/methodgraph.egg-info/entry_points.txt +2 -0
- methodgraph-0.1.0/methodgraph.egg-info/top_level.txt +1 -0
- methodgraph-0.1.0/pyproject.toml +24 -0
- methodgraph-0.1.0/setup.cfg +4 -0
- methodgraph-0.1.0/setup.py +10 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Antigravity
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS IN Schnitt ODER OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include methodgraph/templates *
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: methodgraph
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Graphical flow debugger for Python method calls, arguments, return values, and execution flow.
|
|
5
|
+
Author-email: Sagar Kariya <sbkariya99@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: Topic :: Software Development :: Debuggers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# 🔍 methodgraph
|
|
18
|
+
|
|
19
|
+
**Graphical Style Flow Visual Debugger for Python Method Calls, Passed Values, and Execution Flow**
|
|
20
|
+
|
|
21
|
+
- ⚡ **Graphical Style Flow Canvas**: Interactive node-edge workflow DAG with `__start__` and `__end__` boundary capsules, smooth curved Bezier connectors, card-style nodes, pan/zoom, and minimap.
|
|
22
|
+
- 🎬 **Step-by-Step Playback & Time-Travel Scrubber**: Animate function execution flows with live pulsing halos, edge particle streams, and synchronized state inspection.
|
|
23
|
+
- 🔬 **State & Run Inspector**: Split-screen drawer featuring collapsible syntax-highlighted object trees for inputs, outputs, exceptions, execution metadata, and run history.
|
|
24
|
+
- 🌓 **Light & Dark Theme Toggle**: Built-in dark and light mode themes with persistent preferences and auto OS detection.
|
|
25
|
+
- ⏱️ **Trace Waterfall Timeline**: Execution timing visualization broken down by function call duration and concurrency spans.
|
|
26
|
+
- 🌳 **Interactive Call Tree**: Nested collapsible hierarchy of function invocations with inline parameter chips and return status.
|
|
27
|
+
- 📊 **Searchable Data Matrix**: Filter, search, and inspect argument values, types, return values, and error tracebacks.
|
|
28
|
+
- 🖥️ **CLI Runner & Auto Browser Launcher**: Trace scripts automatically without changing source code.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 🚀 Quick Start
|
|
33
|
+
|
|
34
|
+
### 1. Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install methodgraph
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or install locally in editable mode:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git clone https://github.com/example/methodgraph.git
|
|
44
|
+
cd methodgraph
|
|
45
|
+
pip install -e .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 💡 Usage Modes
|
|
51
|
+
|
|
52
|
+
### Option A: Function Decorator `@trace`
|
|
53
|
+
|
|
54
|
+
Trace specific functions and open the graphical visualization when executed:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from methodgraph import trace, show
|
|
58
|
+
|
|
59
|
+
@trace(show_on_exit=True)
|
|
60
|
+
def calculate_tax(amount, rate=0.2):
|
|
61
|
+
return amount * rate
|
|
62
|
+
|
|
63
|
+
@trace
|
|
64
|
+
def process_order(item_id, price, quantity):
|
|
65
|
+
tax = calculate_tax(price * quantity)
|
|
66
|
+
total = (price * quantity) + tax
|
|
67
|
+
return {"item": item_id, "total": total}
|
|
68
|
+
|
|
69
|
+
# Execute methods
|
|
70
|
+
process_order("ITEM-102", price=49.99, quantity=3)
|
|
71
|
+
|
|
72
|
+
# Generates 'methodgraph_report.html' and opens browser
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### Option B: Class Decorator `@trace_class`
|
|
78
|
+
|
|
79
|
+
Trace all methods within a class automatically:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from methodgraph import trace_class, save_report
|
|
83
|
+
|
|
84
|
+
@trace_class
|
|
85
|
+
class DataPipeline:
|
|
86
|
+
def fetch_data(self, source):
|
|
87
|
+
return [10, 20, 30, 40]
|
|
88
|
+
|
|
89
|
+
def transform(self, data, multiplier=2):
|
|
90
|
+
return [x * multiplier for x in data]
|
|
91
|
+
|
|
92
|
+
def run(self):
|
|
93
|
+
raw = self.fetch_data("database")
|
|
94
|
+
return self.transform(raw, multiplier=3)
|
|
95
|
+
|
|
96
|
+
pipeline = DataPipeline()
|
|
97
|
+
pipeline.run()
|
|
98
|
+
|
|
99
|
+
# Save interactive visual report
|
|
100
|
+
save_report("pipeline_report.html")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### Option C: Context Manager `TraceSession`
|
|
106
|
+
|
|
107
|
+
Trace a specific block of code:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from methodgraph import TraceSession
|
|
111
|
+
|
|
112
|
+
with TraceSession(report_path="session_report.html", auto_open=True) as session:
|
|
113
|
+
data = [5, 12, 18, 24]
|
|
114
|
+
avg = sum(data) / len(data)
|
|
115
|
+
print(f"Average: {avg}")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### Option D: CLI Script Tracer (`methodgraph run`)
|
|
121
|
+
|
|
122
|
+
Trace any existing Python script without modifying a single line of code!
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
methodgraph run my_script.py --open
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Additional CLI options:
|
|
129
|
+
- `--open`: Open generated HTML report in browser automatically.
|
|
130
|
+
- `--output report.html`: Specify custom report file path.
|
|
131
|
+
- `--include-stdlib`: Include standard library modules in tracing (disabled by default for clean graphs).
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 🎨 Interactive Features in Graphical Presentation
|
|
136
|
+
|
|
137
|
+
1. **Parameter Inspection**: Click any method node to view exact positional `args` and keyword `kwargs`, object types, formatted values, and line numbers.
|
|
138
|
+
2. **Return & Exception Inspector**: Clear visual distinction between successful returns and unhandled exceptions (highlighted in crimson red with traceback stack).
|
|
139
|
+
3. **Execution Bottleneck Finder**: Identify slowest methods visually on the Gantt timeline or graph heatmap.
|
|
140
|
+
4. **Live Search**: Filter method calls in real-time by method name, argument name, or argument value substring.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 🛠️ Requirements
|
|
145
|
+
|
|
146
|
+
- Python >= 3.8
|
|
147
|
+
- No heavy third-party dependencies required! Generates self-contained HTML/CSS/JS visualizers.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 📜 License
|
|
152
|
+
|
|
153
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
154
|
+
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# 🔍 methodgraph
|
|
2
|
+
|
|
3
|
+
**Graphical Style Flow Visual Debugger for Python Method Calls, Passed Values, and Execution Flow**
|
|
4
|
+
|
|
5
|
+
- ⚡ **Graphical Style Flow Canvas**: Interactive node-edge workflow DAG with `__start__` and `__end__` boundary capsules, smooth curved Bezier connectors, card-style nodes, pan/zoom, and minimap.
|
|
6
|
+
- 🎬 **Step-by-Step Playback & Time-Travel Scrubber**: Animate function execution flows with live pulsing halos, edge particle streams, and synchronized state inspection.
|
|
7
|
+
- 🔬 **State & Run Inspector**: Split-screen drawer featuring collapsible syntax-highlighted object trees for inputs, outputs, exceptions, execution metadata, and run history.
|
|
8
|
+
- 🌓 **Light & Dark Theme Toggle**: Built-in dark and light mode themes with persistent preferences and auto OS detection.
|
|
9
|
+
- ⏱️ **Trace Waterfall Timeline**: Execution timing visualization broken down by function call duration and concurrency spans.
|
|
10
|
+
- 🌳 **Interactive Call Tree**: Nested collapsible hierarchy of function invocations with inline parameter chips and return status.
|
|
11
|
+
- 📊 **Searchable Data Matrix**: Filter, search, and inspect argument values, types, return values, and error tracebacks.
|
|
12
|
+
- 🖥️ **CLI Runner & Auto Browser Launcher**: Trace scripts automatically without changing source code.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 🚀 Quick Start
|
|
17
|
+
|
|
18
|
+
### 1. Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install methodgraph
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or install locally in editable mode:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone https://github.com/example/methodgraph.git
|
|
28
|
+
cd methodgraph
|
|
29
|
+
pip install -e .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 💡 Usage Modes
|
|
35
|
+
|
|
36
|
+
### Option A: Function Decorator `@trace`
|
|
37
|
+
|
|
38
|
+
Trace specific functions and open the graphical visualization when executed:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from methodgraph import trace, show
|
|
42
|
+
|
|
43
|
+
@trace(show_on_exit=True)
|
|
44
|
+
def calculate_tax(amount, rate=0.2):
|
|
45
|
+
return amount * rate
|
|
46
|
+
|
|
47
|
+
@trace
|
|
48
|
+
def process_order(item_id, price, quantity):
|
|
49
|
+
tax = calculate_tax(price * quantity)
|
|
50
|
+
total = (price * quantity) + tax
|
|
51
|
+
return {"item": item_id, "total": total}
|
|
52
|
+
|
|
53
|
+
# Execute methods
|
|
54
|
+
process_order("ITEM-102", price=49.99, quantity=3)
|
|
55
|
+
|
|
56
|
+
# Generates 'methodgraph_report.html' and opens browser
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### Option B: Class Decorator `@trace_class`
|
|
62
|
+
|
|
63
|
+
Trace all methods within a class automatically:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from methodgraph import trace_class, save_report
|
|
67
|
+
|
|
68
|
+
@trace_class
|
|
69
|
+
class DataPipeline:
|
|
70
|
+
def fetch_data(self, source):
|
|
71
|
+
return [10, 20, 30, 40]
|
|
72
|
+
|
|
73
|
+
def transform(self, data, multiplier=2):
|
|
74
|
+
return [x * multiplier for x in data]
|
|
75
|
+
|
|
76
|
+
def run(self):
|
|
77
|
+
raw = self.fetch_data("database")
|
|
78
|
+
return self.transform(raw, multiplier=3)
|
|
79
|
+
|
|
80
|
+
pipeline = DataPipeline()
|
|
81
|
+
pipeline.run()
|
|
82
|
+
|
|
83
|
+
# Save interactive visual report
|
|
84
|
+
save_report("pipeline_report.html")
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### Option C: Context Manager `TraceSession`
|
|
90
|
+
|
|
91
|
+
Trace a specific block of code:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from methodgraph import TraceSession
|
|
95
|
+
|
|
96
|
+
with TraceSession(report_path="session_report.html", auto_open=True) as session:
|
|
97
|
+
data = [5, 12, 18, 24]
|
|
98
|
+
avg = sum(data) / len(data)
|
|
99
|
+
print(f"Average: {avg}")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### Option D: CLI Script Tracer (`methodgraph run`)
|
|
105
|
+
|
|
106
|
+
Trace any existing Python script without modifying a single line of code!
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
methodgraph run my_script.py --open
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Additional CLI options:
|
|
113
|
+
- `--open`: Open generated HTML report in browser automatically.
|
|
114
|
+
- `--output report.html`: Specify custom report file path.
|
|
115
|
+
- `--include-stdlib`: Include standard library modules in tracing (disabled by default for clean graphs).
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 🎨 Interactive Features in Graphical Presentation
|
|
120
|
+
|
|
121
|
+
1. **Parameter Inspection**: Click any method node to view exact positional `args` and keyword `kwargs`, object types, formatted values, and line numbers.
|
|
122
|
+
2. **Return & Exception Inspector**: Clear visual distinction between successful returns and unhandled exceptions (highlighted in crimson red with traceback stack).
|
|
123
|
+
3. **Execution Bottleneck Finder**: Identify slowest methods visually on the Gantt timeline or graph heatmap.
|
|
124
|
+
4. **Live Search**: Filter method calls in real-time by method name, argument name, or argument value substring.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 🛠️ Requirements
|
|
129
|
+
|
|
130
|
+
- Python >= 3.8
|
|
131
|
+
- No heavy third-party dependencies required! Generates self-contained HTML/CSS/JS visualizers.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 📜 License
|
|
136
|
+
|
|
137
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
138
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
methodgraph - Graphical visual flow debugger for Python method calls & passed values.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .tracer import trace, trace_class, TraceSession, get_active_collector, reset_active_collector
|
|
6
|
+
from .renderer import render_and_save, open_in_browser
|
|
7
|
+
|
|
8
|
+
__version__ = "0.1.0"
|
|
9
|
+
__all__ = [
|
|
10
|
+
"trace",
|
|
11
|
+
"trace_class",
|
|
12
|
+
"TraceSession",
|
|
13
|
+
"save_report",
|
|
14
|
+
"show",
|
|
15
|
+
"__version__",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
def save_report(output_path: str = "methodgraph_report.html") -> str:
|
|
19
|
+
"""Saves current active execution trace to an interactive HTML report file."""
|
|
20
|
+
collector = get_active_collector()
|
|
21
|
+
summary = collector.build_summary()
|
|
22
|
+
return render_and_save(summary, output_path)
|
|
23
|
+
|
|
24
|
+
def show(output_path: str = "methodgraph_report.html"):
|
|
25
|
+
"""Saves current trace and opens the graphical report in default browser."""
|
|
26
|
+
path = save_report(output_path)
|
|
27
|
+
open_in_browser(path)
|
|
28
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
from .tracer import SystemTracer, get_active_collector
|
|
6
|
+
from .renderer import render_and_save, open_in_browser
|
|
7
|
+
from .server import serve_report
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
parser = argparse.ArgumentParser(
|
|
11
|
+
prog="methodgraph",
|
|
12
|
+
description="methodgraph: Graphical style visual debugger and flow tracer for Python method calls & passed values."
|
|
13
|
+
)
|
|
14
|
+
subparsers = parser.add_subparsers(dest="command", help="Available subcommands")
|
|
15
|
+
|
|
16
|
+
# Command: run
|
|
17
|
+
run_parser = subparsers.add_parser("run", help="Run and trace a Python script dynamically.")
|
|
18
|
+
run_parser.add_argument("script", help="Path to Python script to trace.")
|
|
19
|
+
run_parser.add_argument("-o", "--output", default="methodgraph_report.html", help="Report output file path (default: methodgraph_report.html).")
|
|
20
|
+
run_parser.add_argument("--open", action="store_true", help="Automatically open report in browser when finished.")
|
|
21
|
+
run_parser.add_argument("--include-stdlib", action="store_true", help="Include Python standard library calls in trace.")
|
|
22
|
+
run_parser.add_argument("script_args", nargs=argparse.REMAINDER, help="Arguments to pass to target script.")
|
|
23
|
+
|
|
24
|
+
# Command: view / serve
|
|
25
|
+
view_parser = subparsers.add_parser("view", help="View/Serve an existing report file.")
|
|
26
|
+
view_parser.add_argument("report", nargs="?", default="methodgraph_report.html", help="Path to report HTML file.")
|
|
27
|
+
view_parser.add_argument("-p", "--port", type=int, default=8080, help="Port to serve report on (default: 8080).")
|
|
28
|
+
|
|
29
|
+
args = parser.parse_args()
|
|
30
|
+
|
|
31
|
+
if not args.command:
|
|
32
|
+
parser.print_help()
|
|
33
|
+
sys.exit(1)
|
|
34
|
+
|
|
35
|
+
if args.command == "run":
|
|
36
|
+
script_path = os.path.abspath(args.script)
|
|
37
|
+
if not os.path.exists(script_path):
|
|
38
|
+
print(f"[methodgraph] Error: Script '{script_path}' not found.")
|
|
39
|
+
sys.exit(1)
|
|
40
|
+
|
|
41
|
+
sys.argv = [script_path] + (args.script_args or [])
|
|
42
|
+
|
|
43
|
+
sys_tracer = SystemTracer(include_stdlib=args.include_stdlib)
|
|
44
|
+
collector = get_active_collector()
|
|
45
|
+
|
|
46
|
+
print(f"[methodgraph] Tracing script: {script_path}...")
|
|
47
|
+
sys.settrace(sys_tracer.trace_dispatch)
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
with open(script_path, "r", encoding="utf-8") as f:
|
|
51
|
+
code_content = f.read()
|
|
52
|
+
global_scope = {
|
|
53
|
+
"__file__": script_path,
|
|
54
|
+
"__name__": "__main__",
|
|
55
|
+
"__doc__": None,
|
|
56
|
+
"__package__": None,
|
|
57
|
+
}
|
|
58
|
+
compiled_code = compile(code_content, script_path, 'exec')
|
|
59
|
+
exec(compiled_code, global_scope)
|
|
60
|
+
except BaseException as e:
|
|
61
|
+
if not isinstance(e, SystemExit):
|
|
62
|
+
print(f"[methodgraph] Script execution error: {e}")
|
|
63
|
+
finally:
|
|
64
|
+
sys.settrace(None)
|
|
65
|
+
|
|
66
|
+
summary = collector.build_summary()
|
|
67
|
+
output_file = render_and_save(summary, args.output)
|
|
68
|
+
print(f"[methodgraph] Visual trace saved to: {output_file} ({summary['total_calls']} method calls captured)")
|
|
69
|
+
|
|
70
|
+
if args.open:
|
|
71
|
+
open_in_browser(output_file)
|
|
72
|
+
|
|
73
|
+
elif args.command == "view":
|
|
74
|
+
serve_report(args.report, port=args.port, open_browser=True)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if __name__ == "__main__":
|
|
78
|
+
main()
|
|
79
|
+
|