Skip to content

Commit ce2f7c3

Browse files
📝 [mkdocs] Add mkdocs for documentation
1 parent f525b48 commit ce2f7c3

File tree

15 files changed

+4372
-18
lines changed

15 files changed

+4372
-18
lines changed

.github/workflows/docs.yml

Lines changed: 100 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,118 @@
1-
name: Build and Deploy Docs
1+
name: Deploy Documentation
2+
23
on:
34
push:
45
branches:
56
- main
6-
7+
- master
8+
pull_request:
9+
branches:
10+
- main
11+
- master
12+
713
permissions:
8-
contents: write
14+
contents: read
15+
pages: write
16+
id-token: write
17+
18+
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19+
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
20+
concurrency:
21+
group: "pages"
22+
cancel-in-progress: false
923

1024
jobs:
11-
build-and-deploy:
25+
# Build job
26+
build:
1227
runs-on: ubuntu-latest
1328
steps:
14-
- uses: actions/checkout@v2
29+
- name: Checkout
30+
uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 0
1533

16-
- name: Set up Python
17-
uses: actions/setup-python@v2
34+
- name: Setup Python
35+
uses: actions/setup-python@v5
1836
with:
1937
python-version: '3.11'
20-
38+
39+
- name: Cache dependencies
40+
uses: actions/cache@v4
41+
with:
42+
path: ~/.cache/pip
43+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
44+
restore-keys: |
45+
${{ runner.os }}-pip-
46+
2147
- name: Install dependencies
2248
run: |
2349
python -m pip install --upgrade pip
24-
pip install -e ".[dev]" # This will install all dev dependencies including sphinx
25-
26-
- name: Build docs
50+
pip install mkdocs-material
51+
pip install mkdocstrings[python]
52+
pip install pymdown-extensions
53+
# Install the package itself for API documentation
54+
pip install -e .
55+
56+
- name: Setup Pages
57+
id: pages
58+
uses: actions/configure-pages@v4
59+
60+
- name: Build documentation
2761
run: |
28-
sphinx-apidoc -o docs mukh
29-
cd docs
30-
make html
31-
62+
mkdocs build --clean --strict
63+
64+
- name: Upload artifact
65+
uses: actions/upload-pages-artifact@v3
66+
with:
67+
path: ./site
68+
69+
# Deployment job
70+
deploy:
71+
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
72+
environment:
73+
name: github-pages
74+
url: ${{ steps.deployment.outputs.page_url }}
75+
runs-on: ubuntu-latest
76+
needs: build
77+
steps:
3278
- name: Deploy to GitHub Pages
33-
uses: peaceiris/actions-gh-pages@v3
79+
id: deployment
80+
uses: actions/deploy-pages@v4
81+
82+
# Test documentation build on PRs
83+
test-docs:
84+
if: github.event_name == 'pull_request'
85+
runs-on: ubuntu-latest
86+
steps:
87+
- name: Checkout
88+
uses: actions/checkout@v4
89+
90+
- name: Setup Python
91+
uses: actions/setup-python@v5
92+
with:
93+
python-version: '3.11'
94+
95+
- name: Install dependencies
96+
run: |
97+
python -m pip install --upgrade pip
98+
pip install mkdocs-material
99+
pip install mkdocstrings[python]
100+
pip install pymdown-extensions
101+
# Install the package itself for API documentation
102+
pip install -e .
103+
104+
- name: Test documentation build
105+
run: |
106+
mkdocs build --clean --strict
107+
108+
- name: Comment PR
109+
if: github.event_name == 'pull_request'
110+
uses: actions/github-script@v7
34111
with:
35-
github_token: ${{ secrets.GITHUB_TOKEN }}
36-
publish_dir: ./docs/_build/html
112+
script: |
113+
github.rest.issues.createComment({
114+
issue_number: context.issue.number,
115+
owner: context.repo.owner,
116+
repo: context.repo.repo,
117+
body: '✅ Documentation build test passed!'
118+
})

docs/api/core.md

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
# Core Concepts
2+
3+
This section covers the fundamental concepts, data structures, and patterns used throughout Mukh.
4+
5+
## Detection Results
6+
7+
All detection modules return structured data objects that provide consistent access to results.
8+
9+
### Face Detection Results
10+
11+
Face detection methods return lists of detection objects with bounding box information:
12+
13+
```python
14+
from mukh.face_detection import FaceDetector
15+
16+
detector = FaceDetector.create("mediapipe")
17+
detections = detector.detect("image.jpg")
18+
19+
# Each detection contains bounding box and confidence
20+
for detection in detections:
21+
print(f"Confidence: {detection.bbox.confidence}")
22+
print(f"Position: ({detection.bbox.x1}, {detection.bbox.y1}) to ({detection.bbox.x2}, {detection.bbox.y2})")
23+
print(f"Size: {detection.bbox.width} x {detection.bbox.height}")
24+
25+
# Some models provide facial landmarks
26+
if hasattr(detection, 'landmarks') and detection.landmarks is not None:
27+
print(f"Landmarks: {len(detection.landmarks)} points")
28+
```
29+
30+
### Deepfake Detection Results
31+
32+
Deepfake detection returns classification results with confidence scores:
33+
34+
```python
35+
from mukh.deepfake_detection import DeepfakeDetector
36+
37+
detector = DeepfakeDetector("efficientnet")
38+
result = detector.detect("image.jpg")
39+
40+
# Single image result
41+
print(f"Is deepfake: {result.is_deepfake}")
42+
print(f"Confidence: {result.confidence}")
43+
print(f"Model used: {result.model_name}")
44+
45+
# Video results (list of frame results)
46+
video_results = detector.detect("video.mp4", num_frames=10)
47+
for frame_result in video_results:
48+
print(f"Frame {frame_result.frame_number}: {frame_result.is_deepfake} (conf: {frame_result.confidence})")
49+
```
50+
51+
## Common Patterns
52+
53+
### Model Selection
54+
55+
All modules use a factory pattern for model creation:
56+
57+
```python
58+
# Face Detection - choose from blazeface, mediapipe, ultralight
59+
face_detector = FaceDetector.create("mediapipe")
60+
61+
# Deepfake Detection - choose from resnet_inception, resnext, efficientnet
62+
deepfake_detector = DeepfakeDetector("efficientnet")
63+
64+
# Face Reenactment - currently supports tps
65+
reenactor = FaceReenactor.create("tps")
66+
```
67+
68+
### File I/O Patterns
69+
70+
All modules support flexible input/output options:
71+
72+
```python
73+
# Basic detection with file paths
74+
detections = detector.detect(
75+
image_path="input.jpg",
76+
save_csv=True,
77+
csv_path="results.csv",
78+
save_annotated=True,
79+
output_folder="output"
80+
)
81+
82+
# Video processing with frame sampling
83+
results = detector.detect(
84+
media_path="video.mp4",
85+
num_frames=15, # Sample 15 frames
86+
output_folder="video_analysis"
87+
)
88+
```
89+
90+
### Batch Processing
91+
92+
Process multiple files efficiently:
93+
94+
```python
95+
import os
96+
from mukh.face_detection import FaceDetector
97+
98+
detector = FaceDetector.create("mediapipe")
99+
100+
# Process all images in a directory
101+
image_dir = "input_images"
102+
for filename in os.listdir(image_dir):
103+
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
104+
image_path = os.path.join(image_dir, filename)
105+
106+
detections = detector.detect(
107+
image_path=image_path,
108+
save_csv=True,
109+
output_folder=f"output/{filename.split('.')[0]}"
110+
)
111+
print(f"{filename}: {len(detections)} detections")
112+
```
113+
114+
## Configuration Patterns
115+
116+
### Confidence Thresholds
117+
118+
Control detection sensitivity across modules:
119+
120+
```python
121+
# Face detection with custom confidence
122+
detector = FaceDetector.create("blazeface")
123+
# Note: confidence filtering happens in post-processing
124+
125+
# Deepfake detection with threshold
126+
deepfake_detector = DeepfakeDetector("resnext", confidence_threshold=0.7)
127+
128+
# Check if result meets threshold
129+
result = deepfake_detector.detect("image.jpg")
130+
if result.confidence >= 0.7:
131+
print(f"High confidence detection: {result.is_deepfake}")
132+
```
133+
134+
### Output Customization
135+
136+
Control what gets saved and where:
137+
138+
```python
139+
# Minimal output - just get results
140+
detections = detector.detect("image.jpg")
141+
142+
# Save CSV results only
143+
detections = detector.detect(
144+
"image.jpg",
145+
save_csv=True,
146+
csv_path="detections.csv"
147+
)
148+
149+
# Save annotated images with custom folder
150+
detections = detector.detect(
151+
"image.jpg",
152+
save_annotated=True,
153+
output_folder="annotated_results"
154+
)
155+
156+
# Full output - save everything
157+
detections = detector.detect(
158+
"image.jpg",
159+
save_csv=True,
160+
csv_path="detections.csv",
161+
save_annotated=True,
162+
output_folder="full_results"
163+
)
164+
```
165+
166+
## Error Handling
167+
168+
### Input Validation
169+
170+
```python
171+
import os
172+
from mukh.face_detection import FaceDetector
173+
174+
def safe_detection(image_path):
175+
"""Safely perform face detection with validation."""
176+
# Validate file exists
177+
if not os.path.exists(image_path):
178+
raise FileNotFoundError(f"Image not found: {image_path}")
179+
180+
# Validate file format
181+
valid_formats = ('.jpg', '.jpeg', '.png', '.bmp')
182+
if not image_path.lower().endswith(valid_formats):
183+
raise ValueError(f"Unsupported format. Use: {valid_formats}")
184+
185+
try:
186+
detector = FaceDetector.create("mediapipe")
187+
return detector.detect(image_path)
188+
except Exception as e:
189+
print(f"Detection failed: {e}")
190+
return []
191+
```
192+
193+
### Graceful Degradation
194+
195+
```python
196+
def robust_analysis(media_path):
197+
"""Analyze media with fallback options."""
198+
# Try multiple models in order of preference
199+
models = ["efficientnet", "resnet_inception", "resnext"]
200+
201+
for model_name in models:
202+
try:
203+
detector = DeepfakeDetector(model_name)
204+
return detector.detect(media_path)
205+
except Exception as e:
206+
print(f"Model {model_name} failed: {e}")
207+
continue
208+
209+
raise RuntimeError("All models failed")
210+
```
211+
212+
## Performance Considerations
213+
214+
### Model Selection Guide
215+
216+
| Use Case | Recommended Model | Trade-offs |
217+
|----------|------------------|------------|
218+
| **Face Detection** | | |
219+
| Real-time/Mobile | `blazeface` | Fast, lower accuracy |
220+
| General purpose | `mediapipe` | Balanced speed/accuracy |
221+
| CPU-only | `ultralight` | Optimized for CPU |
222+
| **Deepfake Detection** | | |
223+
| High accuracy | `resnext` | Slower, more memory |
224+
| Balanced | `resnet_inception` | Good all-around |
225+
| Speed optimized | `efficientnet` | Faster inference |
226+
227+
### Memory Management
228+
229+
```python
230+
# Process large batches efficiently
231+
import gc
232+
from mukh.face_detection import FaceDetector
233+
234+
detector = FaceDetector.create("mediapipe")
235+
236+
for batch_start in range(0, len(image_list), batch_size):
237+
batch = image_list[batch_start:batch_start + batch_size]
238+
239+
for image_path in batch:
240+
detections = detector.detect(image_path)
241+
# Process results...
242+
243+
# Clear memory between batches
244+
gc.collect()
245+
```
246+
```

0 commit comments

Comments
 (0)