Skip to content

Commit 6262244

Browse files
Merge pull request #5 from ahmed-n-abdeltwab/feature/make-modular
Refactor: Transform project into a modular and dynamic structure
2 parents e987ac3 + 8c67416 commit 6262244

33 files changed

+1043
-907
lines changed

.dockerignore

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
__pycache__/
2-
*.pyc
3-
*.pyo
4-
*.pyd
1+
**/__pycache__
2+
**/*.pyc
3+
**/*.pyo
4+
**/*.pyd
55
venv/
66
.env
7-
data/raw/
8-
data/processed/
9-
models/saved/
10-
__init__.py
117
.DS_Store
8+
*.log
9+
*.sqlite3
10+
*.zip
11+
*.tar.gz
12+
.pytest_cache/
13+
.idea/
14+
.vscode/

.github/workflows/train_and_release.yml

+52-18
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,80 @@ name: Train and Release Model
22

33
on:
44
push:
5-
branches:
6-
- main # Trigger when pushing to main
7-
workflow_dispatch: # Allow manual trigger
5+
branches: [ main ]
6+
workflow_dispatch:
7+
8+
env:
9+
DOCKER_IMAGE: spyware-detector
10+
RELEASE_DIR: release
811

912
jobs:
1013
train-and-release:
1114
runs-on: ubuntu-latest
1215
permissions:
1316
contents: write
17+
packages: write
18+
actions: read
19+
1420
steps:
15-
- name: Checkout Repository
21+
- name: Checkout repository
1622
uses: actions/checkout@v3
1723

18-
- name: Set up Python
24+
- name: Set up Python 3.9
1925
uses: actions/setup-python@v4
2026
with:
2127
python-version: '3.9'
2228

23-
- name: Install Dependencies
29+
- name: Install dependencies
2430
run: |
31+
python -m pip install --upgrade pip
2532
pip install -r requirements.txt
2633
27-
- name: Train the Model
34+
- name: Build Docker image
35+
run: docker build -t $DOCKER_IMAGE .
36+
37+
- name: Run training pipeline
2838
run: |
29-
python main.py # Modify if needed to run training
39+
mkdir -p ./$RELEASE_DIR
40+
docker run --rm \
41+
-v $(pwd)/data:/app/data \
42+
-v $(pwd)/models:/app/models \
43+
-v $(pwd)/$RELEASE_DIR:/app/$RELEASE_DIR \
44+
$DOCKER_IMAGE
3045
31-
- name: Archive Model
46+
- name: Verify artifacts
3247
run: |
33-
mkdir -p release
34-
cp models/saved/*/model.pkl release/model.pkl
35-
cp models/saved/*/metadata.json release/metadata.json
36-
cp models/saved/*/metrics.json release/metrics.json
37-
tar -czvf trained_model.tar.gz -C release .
48+
echo "Generated artifacts:"
49+
ls -lR ./$RELEASE_DIR
50+
[ -f ./$RELEASE_DIR/latest/model.pkl ] || exit 1
51+
[ -f ./$RELEASE_DIR/latest/metadata.json ] || exit 1
52+
53+
- name: Create release package
54+
run: |
55+
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
56+
RELEASE_NAME="model_$TIMESTAMP"
57+
mkdir -p ./$RELEASE_DIR/$RELEASE_NAME
58+
cp -r ./$RELEASE_DIR/latest/* ./$RELEASE_DIR/$RELEASE_NAME/
59+
tar -czvf ./$RELEASE_DIR/$RELEASE_NAME.tar.gz -C ./$RELEASE_DIR/$RELEASE_NAME .
60+
61+
- name: Upload artifact
62+
uses: actions/upload-artifact@v3
63+
with:
64+
name: model-release
65+
path: ./$RELEASE_DIR/*.tar.gz
3866

3967
- name: Create GitHub Release
68+
if: startsWith(github.ref, 'refs/tags/')
4069
uses: softprops/action-gh-release@v1
4170
with:
42-
tag_name: latest-model-${{ github.run_number }}
43-
name: Latest Trained Model
44-
body: "This model was trained automatically on commit ${{ github.sha }}"
45-
files: trained_model.tar.gz
71+
name: "Model Release $(date +'%Y-%m-%d')"
72+
body: |
73+
Automated model training results:
74+
- Model: $(jq -r '.model_type' ./$RELEASE_DIR/latest/metadata.json)
75+
- Timestamp: $(jq -r '.timestamp' ./$RELEASE_DIR/latest/metadata.json)
76+
- Metrics:
77+
Accuracy: $(jq -r '.metrics.accuracy' ./$RELEASE_DIR/latest/metrics.json)
78+
F1 Score: $(jq -r '.metrics.f1' ./$RELEASE_DIR/latest/metrics.json)
79+
files: ./$RELEASE_DIR/*.tar.gz
4680
env:
4781
GITHUB_TOKEN: ${{ secrets.GH_PAT }}

.gitignore

+48-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,53 @@
1+
# Byte-compiled / optimized / DLL files
12
__pycache__/
2-
*.pyc
3-
*.pyo
4-
*.pyd
3+
*.py[cod]
4+
*$py.class
5+
6+
# Virtual environment
57
venv/
6-
.env
8+
.env/
9+
.venv/
10+
11+
# IDE specific files
12+
.idea/
13+
.vscode/
14+
*.swp
15+
*.swo
16+
17+
# Data files
18+
data/raw/
719
data/processed/
20+
*.csv
21+
*.pkl
22+
*.pickle
23+
24+
# Model files
825
models/saved/
9-
.DS_Store
10-
__init__.py
26+
*.pth
27+
*.h5
28+
*.joblib
29+
30+
# Log files
1131
*.log
12-
*.sqlite3
32+
logs/
33+
34+
# System files
35+
.DS_Store
36+
Thumbs.db
37+
38+
# Release packages
39+
release/
40+
*.zip
41+
*.tar.gz
42+
43+
# Test coverage
44+
.coverage
45+
htmlcov/
46+
.pytest_cache/
47+
48+
# Jupyter notebooks
49+
*.ipynb
50+
.ipynb_checkpoints/
51+
52+
# Documentation
53+
docs/_build/

Dockerfile

+41-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,49 @@
1-
FROM python:3.9-slim
1+
# ========== BUILD STAGE ==========
2+
FROM python:3.9 AS builder
23

3-
# Set the working directory
44
WORKDIR /app
55

6-
# Copy requirement files and install dependencies
6+
# Install system dependencies
7+
RUN apt-get update && \
8+
apt-get install -y --no-install-recommends gcc python3-dev && \
9+
rm -rf /var/lib/apt/lists/*
10+
11+
# Create virtual environment
12+
RUN python -m venv /opt/venv
13+
ENV PATH="/opt/venv/bin:$PATH"
14+
15+
# Install Python dependencies
716
COPY requirements.txt .
817
RUN pip install --no-cache-dir -r requirements.txt
918

10-
# Copy the application code
11-
COPY . .
1219

13-
# Set the entry point
14-
CMD ["python", "main.py"]
20+
# ========== RUNTIME STAGE ==========
21+
FROM python:3.9-slim
22+
23+
ENV PYTHONPATH=/app
24+
25+
# Create non-root user
26+
RUN useradd -m appuser && \
27+
mkdir -p /app && \
28+
chown appuser:appuser /app
29+
30+
WORKDIR /app
31+
USER appuser
32+
33+
# Copy virtual environment
34+
COPY --from=builder /opt/venv /opt/venv
35+
ENV PATH="/opt/venv/bin:$PATH"
36+
37+
# Copy application files
38+
COPY --chown=appuser:appuser src/ ./src/
39+
COPY --chown=appuser:appuser config/ ./config/
40+
41+
# Create data directories
42+
RUN mkdir -p data/raw data/processed models/saved release
43+
44+
# Health check
45+
HEALTHCHECK --interval=30s --timeout=10s \
46+
CMD python -c "import sys; sys.exit(0)"
1547

48+
# Entry point
49+
CMD ["python", "src/main.py"]

0 commit comments

Comments
 (0)