Skip to content

Commit 6c1c371

Browse files
committed
Refactored for Typer compatability
1 parent 3bfe946 commit 6c1c371

File tree

2 files changed

+78
-25
lines changed

2 files changed

+78
-25
lines changed

main.py

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,60 @@
1+
import typer
2+
from typing_extensions import Annotated
13
from scan import scan_url, get_url_report, get_api_key
24
from workbook import save_to_excel
35
from generate import generate_html_report
4-
import argparse
56

7+
app = typer.Typer()
68

7-
def main():
8-
api_key = get_api_key() # Get the API key from user input
99

10-
parser = argparse.ArgumentParser(description="Scan URLs with VirusTotal.")
11-
parser.add_argument(
12-
"urls",
13-
metavar="URL",
14-
type=str,
15-
nargs="+",
16-
help="URLs to scan (space-separated)",
17-
)
18-
args = parser.parse_args()
19-
urls = args.urls
10+
@app.command()
11+
def main(
12+
urls: Annotated[
13+
list[str],
14+
typer.Argument(help="URLs to scan (space-separated)"),
15+
],
16+
api_key: Annotated[
17+
str,
18+
typer.Option(
19+
"--api-key",
20+
"-k",
21+
help="Your VirusTotal API key. If not provided, you will be prompted.",
22+
),
23+
] = None,
24+
):
25+
"""
26+
Scan URLs with VirusTotal and generate reports.
27+
"""
28+
if not api_key:
29+
api_key = get_api_key()
2030

2131
results = []
2232
for url in urls:
23-
scan_id = scan_url(url, api_key) # Pass the API key to scan_url
33+
scan_id = scan_url(url, api_key)
2434
if scan_id:
25-
# Pass the API key to get_url_report
2635
report = get_url_report(scan_id, api_key)
2736
if report:
28-
stats = report.results.get('attributes', {}).get('stats', {})
29-
results.append({
30-
'url': url,
31-
'malicious': stats.get('malicious', 0),
32-
'harmless': stats.get('harmless', 0),
33-
'undetected': stats.get('undetected', 0)
34-
})
37+
attributes = report.get("attributes", {})
38+
stats = attributes.get("stats", {})
39+
results.append(
40+
{
41+
"url": url,
42+
"malicious": stats.get("malicious", 0),
43+
"harmless": stats.get("harmless", 0),
44+
"undetected": stats.get("undetected", 0),
45+
}
46+
)
47+
else:
48+
print(f"No report found for {url}")
49+
else:
50+
print(f"Scan failed for {url}")
3551

36-
save_to_excel(results)
37-
generate_html_report(results)
52+
if results:
53+
save_to_excel(results)
54+
generate_html_report(results)
55+
else:
56+
print("No results to report.")
3857

3958

4059
if __name__ == "__main__":
41-
main()
60+
app()

requirements.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
aiofiles==24.1.0
2+
aiohappyeyeballs==2.6.1
3+
aiohttp==3.11.14
4+
aiosignal==1.3.2
5+
attrs==25.3.0
6+
certifi==2025.1.31
7+
charset-normalizer==3.4.1
8+
click==8.1.8
9+
et_xmlfile==2.0.0
10+
frozenlist==1.5.0
11+
idna==3.10
12+
Jinja2==3.1.6
13+
markdown-it-py==3.0.0
14+
MarkupSafe==3.0.2
15+
mdurl==0.1.2
16+
multidict==6.2.0
17+
numpy==2.2.4
18+
openpyxl==3.1.5
19+
pandas==2.2.3
20+
propcache==0.3.0
21+
Pygments==2.19.1
22+
python-dateutil==2.9.0.post0
23+
python-dotenv==1.1.0
24+
pytz==2025.2
25+
requests==2.32.3
26+
rich==13.9.4
27+
shellingham==1.5.4
28+
six==1.17.0
29+
typer==0.15.2
30+
typing_extensions==4.13.0
31+
tzdata==2025.2
32+
urllib3==2.3.0
33+
vt-py==0.19.0
34+
yarl==1.18.3

0 commit comments

Comments
 (0)