SaiBon99 commited on
Commit
6a0ae1a
·
1 Parent(s): 318768d

Add command-line argument parsing and scheduled data pipeline for batch URL scanning

Browse files
.github/workflows/scheduled_data_pipeline.yml ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Scheduled Data Pipeline
2
+
3
+ on:
4
+ schedule:
5
+ # Load phishing URLs every 24 hours (at midnight UTC)
6
+ - cron: '0 0 * * *'
7
+ # Run batch scanner every 2 hours
8
+ - cron: '0 */2 * * *'
9
+ workflow_dispatch: # Allow manual triggering
10
+ inputs:
11
+ job_to_run:
12
+ description: 'Which job to run'
13
+ required: true
14
+ type: choice
15
+ options:
16
+ - load_phishing_urls
17
+ - batch_scanner
18
+ - both
19
+
20
+ jobs:
21
+ load-phishing-urls:
22
+ name: Load Phishing URLs
23
+ runs-on: ubuntu-latest
24
+ # Only run on midnight schedule or manual trigger
25
+ if: |
26
+ github.event.schedule == '0 0 * * *' ||
27
+ github.event_name == 'workflow_dispatch' &&
28
+ (github.event.inputs.job_to_run == 'load_phishing_urls' || github.event.inputs.job_to_run == 'both')
29
+
30
+ steps:
31
+ - name: Checkout code
32
+ uses: actions/checkout@v4
33
+ with:
34
+ lfs: true # Pull Git LFS files
35
+
36
+ - name: Set up Python
37
+ uses: actions/setup-python@v5
38
+ with:
39
+ python-version: '3.11'
40
+
41
+ - name: Install uv
42
+ uses: astral-sh/setup-uv@v4
43
+ with:
44
+ version: "latest"
45
+
46
+ - name: Install dependencies
47
+ run: uv sync --group dev
48
+
49
+ - name: Load phishing URLs to Hopsworks
50
+ env:
51
+ HOPSWORKS_API_KEY: ${{ secrets.HOPSWORKS_API_KEY }}
52
+ HOPSWORKS_PROJECT_NAME: ${{ secrets.HOPSWORKS_PROJECT_NAME }}
53
+ run: |
54
+ uv run python src/phising_detection/data/load_phishing_urls.py
55
+
56
+ batch-url-scanner:
57
+ name: Batch URL Scanner
58
+ runs-on: ubuntu-latest
59
+ # Run on 2-hour schedule or manual trigger
60
+ if: |
61
+ github.event.schedule == '0 */2 * * *' ||
62
+ github.event_name == 'workflow_dispatch' &&
63
+ (github.event.inputs.job_to_run == 'batch_scanner' || github.event.inputs.job_to_run == 'both')
64
+
65
+ steps:
66
+ - name: Checkout code
67
+ uses: actions/checkout@v4
68
+ with:
69
+ lfs: true
70
+
71
+ - name: Set up Python
72
+ uses: actions/setup-python@v5
73
+ with:
74
+ python-version: '3.11'
75
+
76
+ - name: Install uv
77
+ uses: astral-sh/setup-uv@v4
78
+ with:
79
+ version: "latest"
80
+
81
+ - name: Install dependencies
82
+ run: uv sync --group dev
83
+
84
+ - name: Run batch URL scanner
85
+ env:
86
+ URLSCAN_API_KEY: ${{ secrets.URLSCAN_API_KEY }}
87
+ HOPSWORKS_API_KEY: ${{ secrets.HOPSWORKS_API_KEY }}
88
+ HOPSWORKS_PROJECT_NAME: ${{ secrets.HOPSWORKS_PROJECT_NAME }}
89
+ run: |
90
+ uv run python src/phising_detection/features/batch_url_scanner.py \
91
+ --fg1-name phishing_urls \
92
+ --fg1-version 2 \
93
+ --fg2-name legit_urls_before_scan \
94
+ --fg2-version 1 \
95
+ --output-fg-name urlscan_features \
96
+ --output-version 1 \
97
+ --batch-size 500 \
98
+ --sample-size 500
99
+ timeout-minutes: 30 # Prevent job from running too long
src/phising_detection/features/batch_url_scanner.py CHANGED
@@ -12,6 +12,7 @@ import sys
12
  import os
13
  import logging
14
  import time
 
15
  from typing import List, Dict, Any
16
  import pandas as pd
17
 
@@ -612,15 +613,74 @@ def main(
612
  logger.info("=" * 80)
613
 
614
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615
  if __name__ == "__main__":
616
- # Example usage - adjust parameters as needed
 
617
  main(
618
- fg1_name="phishing_urls",
619
- fg1_version=2,
620
- fg2_name="legit_urls_before_scan",
621
- fg2_version=1,
622
- output_fg_name="urlscan_features",
623
- output_version=1,
624
- batch_size=300,
625
- sample_size=None # Set to None to use all available data
626
  )
 
12
  import os
13
  import logging
14
  import time
15
+ import argparse
16
  from typing import List, Dict, Any
17
  import pandas as pd
18
 
 
613
  logger.info("=" * 80)
614
 
615
 
616
+ def parse_args():
617
+ """Parse command-line arguments."""
618
+ parser = argparse.ArgumentParser(
619
+ description="Batch URL scanning pipeline for phishing detection"
620
+ )
621
+
622
+ parser.add_argument(
623
+ "--fg1-name",
624
+ type=str,
625
+ default="phishing_urls",
626
+ help="Name of first feature group (default: phishing_urls)"
627
+ )
628
+ parser.add_argument(
629
+ "--fg1-version",
630
+ type=int,
631
+ default=2,
632
+ help="Version of first feature group (default: 2)"
633
+ )
634
+ parser.add_argument(
635
+ "--fg2-name",
636
+ type=str,
637
+ default="legitimate_urls",
638
+ help="Name of second feature group (default: legitimate_urls)"
639
+ )
640
+ parser.add_argument(
641
+ "--fg2-version",
642
+ type=int,
643
+ default=1,
644
+ help="Version of second feature group (default: 1)"
645
+ )
646
+ parser.add_argument(
647
+ "--output-fg-name",
648
+ type=str,
649
+ default="urlscan_features",
650
+ help="Name of output feature group (default: urlscan_features)"
651
+ )
652
+ parser.add_argument(
653
+ "--output-version",
654
+ type=int,
655
+ default=1,
656
+ help="Version of output feature group (default: 1)"
657
+ )
658
+ parser.add_argument(
659
+ "--batch-size",
660
+ type=int,
661
+ default=200,
662
+ help="Number of URLs to scan per batch (default: 200)"
663
+ )
664
+ parser.add_argument(
665
+ "--sample-size",
666
+ type=int,
667
+ default=None,
668
+ help="Number of samples from each input group (default: None = use all)"
669
+ )
670
+
671
+ return parser.parse_args()
672
+
673
+
674
  if __name__ == "__main__":
675
+ args = parse_args()
676
+
677
  main(
678
+ fg1_name=args.fg1_name,
679
+ fg1_version=args.fg1_version,
680
+ fg2_name=args.fg2_name,
681
+ fg2_version=args.fg2_version,
682
+ output_fg_name=args.output_fg_name,
683
+ output_version=args.output_version,
684
+ batch_size=args.batch_size,
685
+ sample_size=args.sample_size
686
  )