pawpy-cli 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,712 @@
1
+ Metadata-Version: 2.4
2
+ Name: pawpy-cli
3
+ Version: 1.0.0
4
+ Summary: Advanced wordlist generator for OSINT, pentesting, and security research
5
+ Author-email: Danyal Khattak <Danyalkhattak739@icloud.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Danyalkhattak/pawpy
8
+ Project-URL: Documentation, https://github.com/Danyalkhattak/pawpy#readme
9
+ Project-URL: Repository, https://github.com/Danyalkhattak/pawpy
10
+ Project-URL: Issues, https://github.com/Danyalkhattak/pawpy/issues
11
+ Keywords: wordlist,password,osint,pentesting,cybersecurity,security,dictionary,generator,cli,redteam
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Education
15
+ Classifier: Intended Audience :: Information Technology
16
+ Classifier: Intended Audience :: System Administrators
17
+ Classifier: Topic :: Security
18
+ Classifier: Topic :: Utilities
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
26
+ Classifier: Operating System :: OS Independent
27
+ Classifier: Environment :: Console
28
+ Requires-Python: >=3.10
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Requires-Dist: rich>=13.7.1
32
+ Requires-Dist: pyfiglet>=1.0.2
33
+ Requires-Dist: zxcvbn>=4.4.28
34
+ Provides-Extra: api
35
+ Requires-Dist: fastapi>=0.115.0; extra == "api"
36
+ Requires-Dist: uvicorn>=0.35.0; extra == "api"
37
+ Requires-Dist: python-multipart>=0.0.20; extra == "api"
38
+ Provides-Extra: gpu
39
+ Requires-Dist: cupy-cuda12x>=13.0.0; extra == "gpu"
40
+ Provides-Extra: websocket
41
+ Requires-Dist: websockets>=12.0; extra == "websocket"
42
+ Provides-Extra: all
43
+ Requires-Dist: fastapi>=0.115.0; extra == "all"
44
+ Requires-Dist: uvicorn>=0.35.0; extra == "all"
45
+ Requires-Dist: python-multipart>=0.0.20; extra == "all"
46
+ Requires-Dist: cupy-cuda12x>=13.0.0; extra == "all"
47
+ Requires-Dist: websockets>=12.0; extra == "all"
48
+ Dynamic: license-file
49
+
50
+ # Pawpy
51
+
52
+ **The Most Powerful Wordlist Generator**
53
+
54
+ <p align="center">
55
+ <img src="https://img.shields.io/badge/version-1.0.0-blue" alt="Version" />
56
+ <img src="https://img.shields.io/badge/python-3.8+-green" alt="Python" />
57
+ <img src="https://img.shields.io/badge/license-MIT-orange" alt="License" />
58
+ <img src="https://img.shields.io/badge/purpose-educational%20%7C%20authorised%20testing-red" alt="Purpose" />
59
+ </p>
60
+
61
+ ---
62
+
63
+ ## ⚠️ Ethical Use Only
64
+
65
+ Pawpy is designed **exclusively** for authorised security testing, password audits, and educational purposes. Unauthorised use against systems or accounts you do not own or have explicit permission to test is **illegal and unethical**. By using this tool, you confirm you have proper authorisation.
66
+
67
+ ---
68
+
69
+ ## Table of Contents
70
+
71
+ - [Overview](#overview)
72
+ - [Features](#features)
73
+ - [Installation](#installation)
74
+ - [Quick Start](#quick-start)
75
+ - [CLI Reference](#cli-reference)
76
+ - [Profile Format](#profile-format)
77
+ - [Mutation Engine](#mutation-engine)
78
+ - [Scoring & Filtering](#scoring--filtering)
79
+ - [API & Dashboard](#api--dashboard)
80
+ - [OSINT Plugins](#osint-plugins)
81
+ - [Project Structure](#project-structure)
82
+ - [Development](#development)
83
+ - [License](#license)
84
+
85
+ ---
86
+
87
+ ## Overview
88
+
89
+ Pawpy is an open-source, terminal-based wordlist generator a powerful mutation engine, Markov chain blending, hashcat rule-file support, hybrid mask attacks, and a built-in web dashboard. It transforms target profile information into comprehensive, policy-compliant password candidate lists suitable for authorised penetration testing and security research.
90
+
91
+ The tool follows a modular pipeline architecture: profile data flows through successive mutation stages (leet-speak, mangle rules, date permutations, keyboard walks, Markov blending, custom templates, hashcat rules, hybrid masks) before optional scoring and policy filtering produces the final deduplicated, sorted wordlist.
92
+
93
+ ---
94
+
95
+ ## Features
96
+
97
+ ### Core
98
+
99
+ | Feature | Description |
100
+ |---------|-------------|
101
+ | **Interactive Profiling** | Questionnaire for collecting target information |
102
+ | **JSON Import** | Load single or multi-target profiles from JSON files |
103
+ | **Multi-Target Cross-Referencing** | Merge multiple profiles for cross-referenced word generation |
104
+ | **OSINT Plugin System** | Auto-discovery and execution of OSINT plugins from `profile/plugins/` |
105
+ | **Embedded Top 10K Passwords** | Ships with common passwords; auto-updatable from SecLists |
106
+
107
+ ### Mutation Engine
108
+
109
+ | Mutation | Description |
110
+ |----------|-------------|
111
+ | **Leet Speak** | 3 substitution levels (basic, extended, aggressive) with combinatorial expansion |
112
+ | **Date Permutations** | 20+ variants per date: DDMM, MMDD, YYYY, YY, with separator combinations |
113
+ | **Common Mangle Rules** | Capitalise, upper, lower, reverse, swapcase, append/prepend digits & symbols |
114
+ | **Hashcat Rule Engine** | Full parser for hashcat/John-style `.rule` files (l, u, c, r, $X, ^X, sXY, iNX, oNX, d, p, z, [N, ]N) |
115
+ | **Static Keyboard Walks** | 25+ built-in classic patterns (qwerty, asdf, zxcvbn, 1qaz2wsx, ...) |
116
+ | **Dynamic Keyboard Walks** | BFS-generated walks on QWERTY adjacency graph up to configurable length |
117
+ | **Two-Word Combinations** | All pairs of base words with 8 separator variants and case combinations |
118
+ | **Year-Word Blends** | Append/prepend years (1990–current) and two-digit years to all base words |
119
+ | **Markov Blending** | Character-level Markov chain (order 1–4) trained on corpus + profile words |
120
+ | **Custom Templates** | Pattern engine: `[FirstName][Year][!]` with token resolution and combinatorial expansion |
121
+ | **Hybrid Mask Attacks** | Simulates hashcat `-a 6` (word + right mask) and `-a 7` (left mask + word) |
122
+
123
+ ### Scoring & Filtering
124
+
125
+ | Feature | Description |
126
+ |---------|-------------|
127
+ | **zxcvbn Scoring** | Optional strength-based pruning (scores 0–4) to remove trivially weak candidates |
128
+ | **Policy Filtering** | Enforce minimum length, uppercase, lowercase, digit, and special character requirements |
129
+
130
+ ### API & Dashboard
131
+
132
+ | Feature | Description |
133
+ |---------|-------------|
134
+ | **REST API** | FastAPI endpoint (`POST /generate`) accepting profile JSON, returning download URL |
135
+ | **Web Dashboard** | Browser-based UI with real-time WebSocket progress logging |
136
+
137
+ ### Performance
138
+
139
+ | Feature | Description |
140
+ |---------|-------------|
141
+ | **Multi-Process** | Configurable worker count via `-t` / `--threads` |
142
+ | **GPU Acceleration** | Optional CuPy-based GPU rule application (graceful fallback to CPU) |
143
+ | **External Merge Sort** | Billion-scale sorting with k-way heap merge for very large wordlists |
144
+
145
+ ### Modes
146
+
147
+ | Mode | Flag | Behaviour |
148
+ |------|------|----------|
149
+ | **Normal** | *(default)* | All standard mutations |
150
+ | **Lite** | `--lite` | Skips two-word combos, Markov, large hybrid, dynamic keyboard walks |
151
+ | **Extreme** | `--extreme` | Enables year blends, Markov, dynamic keyboard walks, all heavy mutations |
152
+
153
+ ---
154
+
155
+ ## Installation
156
+
157
+ ### From PyPI (recommended)
158
+
159
+ ```bash
160
+ pip install pawpy
161
+ ```
162
+
163
+ ### From Source
164
+
165
+ ```bash
166
+ git clone https://github.com/Danyalkhattak/pawpy.git
167
+ cd pawpy
168
+ pip install -r requirements.txt
169
+ pip install -e .
170
+ ```
171
+
172
+ ### Optional Dependencies
173
+
174
+ ```bash
175
+ # API & Dashboard
176
+ pip install fastapi uvicorn websockets
177
+
178
+ # GPU acceleration (requires CUDA)
179
+ pip install cupy-cuda11x # or cupy-cuda12x depending on your CUDA version
180
+
181
+ # Password strength scoring
182
+ pip install zxcvbn
183
+
184
+ # All optional
185
+ pip install -e ".[all]"
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Quick Start
191
+
192
+ ### Interactive Mode
193
+
194
+ ```bash
195
+ pawpy
196
+ ```
197
+
198
+ This launches the questionnaire. Answer the prompts (blank answers are fine) and Pawpy generates a wordlist to `pawpy_wordlist.txt`.
199
+
200
+ ### From JSON Profile
201
+
202
+ ```bash
203
+ pawpy -j profile.json -o wordlist.txt
204
+ ```
205
+
206
+ ### Multi-Target Mode
207
+
208
+ ```bash
209
+ pawpy --multi targets.json --extreme
210
+ ```
211
+
212
+ ### With Hashcat Rules
213
+
214
+ ```bash
215
+ pawpy -j profile.json --rules best64.rule
216
+ ```
217
+
218
+ ### Hybrid Mask Attack
219
+
220
+ ```bash
221
+ pawpy -j profile.json --hybrid-right ?d?d?d
222
+ ```
223
+
224
+ ### With Scoring & Policy Filter
225
+
226
+ ```bash
227
+ pawpy -j profile.json --min-strength 2 --min-length 8 --require-upper --require-digit
228
+ ```
229
+
230
+ ### Update Common Passwords
231
+
232
+ ```bash
233
+ pawpy update-passwords
234
+ ```
235
+
236
+ ### Start API Server
237
+
238
+ ```bash
239
+ pawpy api
240
+ # Server runs at http://127.0.0.1:8000
241
+ ```
242
+
243
+ ### Launch Dashboard
244
+
245
+ ```bash
246
+ pawpy dashboard
247
+ # Dashboard runs at http://127.0.0.1:8080
248
+ ```
249
+
250
+ ---
251
+
252
+ ## CLI Reference
253
+
254
+ ```
255
+ usage: pawpy [-h] [-o FILE] [-j FILE] [--multi FILE] [--rules FILE]
256
+ [--template TMPL] [--hybrid-left MASK] [--hybrid-right MASK]
257
+ [--markov] [--markov-order N] [--markov-count N]
258
+ [--min-strength N] [--min-length N]
259
+ [--require-upper] [--require-lower] [--require-digit]
260
+ [--require-special] [--lite] [--extreme]
261
+ [--gpu] [-t N] [-v] [--verbose]
262
+
263
+ Options:
264
+ -o, --output FILE Output file (default: pawpy_wordlist.txt)
265
+ -j, --import-json FILE Import single profile from JSON
266
+ --multi FILE Import multiple profiles from JSON array
267
+ --rules FILE Load hashcat rule file
268
+ --template TEMPLATE Custom pattern template (repeatable)
269
+ --hybrid-left MASK Left mask for hybrid attack (?l?d)
270
+ --hybrid-right MASK Right mask for hybrid attack (?d?d?d)
271
+ --markov Enable Markov chain blending
272
+ --markov-order N Markov chain order (default: 2)
273
+ --markov-count N Number of Markov words (default: 5000)
274
+ --min-strength N Minimum zxcvbn score (0-4)
275
+ --min-length N Minimum password length
276
+ --require-upper Require uppercase letter
277
+ --require-lower Require lowercase letter
278
+ --require-digit Require digit
279
+ --require-special Require special character
280
+ --lite Fast mode (skip heavy combos)
281
+ --extreme Enable all heavy mutations
282
+ --gpu Use GPU acceleration if available
283
+ -t, --threads N Worker process count (default: CPU count)
284
+ -v, --version Show version
285
+ --verbose Enable debug logging
286
+
287
+ Sub-commands:
288
+ update-passwords Download latest common passwords from SecLists
289
+ api Start REST API server
290
+ dashboard Launch web dashboard
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Profile Format
296
+
297
+ ### Single Profile (JSON)
298
+
299
+ ```json
300
+ {
301
+ "firstname": "John",
302
+ "lastname": "Doe",
303
+ "nickname": "Johnny",
304
+ "birthdate": "01011990",
305
+ "partner": "Jane",
306
+ "partner_nick": "Janey",
307
+ "partner_bdate": "02021992",
308
+ "pet": "Rex",
309
+ "company": "Acme",
310
+ "hometown": "Metropolis",
311
+ "favourite_color": "blue",
312
+ "children": ["Alice", "Bob"],
313
+ "keywords": ["guitar", "hiking"]
314
+ }
315
+ ```
316
+
317
+ ### Multi-Target Profile (JSON Array)
318
+
319
+ ```json
320
+ [
321
+ { "firstname": "John", "lastname": "Doe", "pet": "Rex" },
322
+ { "firstname": "Jane", "lastname": "Doe", "pet": "Buddy" }
323
+ ]
324
+ ```
325
+
326
+ When using `--multi`, Pawpy merges all profiles into a unified cross-referenced profile. This means base words from all targets are combined, enabling the mutation engine to generate cross-target combinations (e.g., John's first name paired with Jane's pet name).
327
+
328
+ ---
329
+
330
+ ## Mutation Engine
331
+
332
+ The mutation pipeline processes base words through multiple stages in sequence:
333
+
334
+ ```
335
+ Base Words
336
+
337
+ ├── Leet Speak (3 levels)
338
+ ├── Common Mangle Rules (capitalize, reverse, append/prepend)
339
+ ├── Date Permutations (20+ variants per date)
340
+ ├── Hashcat Rules (if --rules provided)
341
+ ├── Custom Templates (if --template provided)
342
+ ├── Keyboard Walks (static + optional dynamic)
343
+ ├── Markov Blending (if --markov)
344
+ ├── Year-Word Blends (if not --lite)
345
+ ├── Two-Word Combinations (if not --lite)
346
+ ├── Hybrid Masks (if --hybrid-left/right)
347
+ └── Top 10K Common Passwords
348
+
349
+
350
+ Scoring & Policy Filtering
351
+
352
+
353
+ Deduplication & Sort → Final Wordlist
354
+ ```
355
+
356
+ ### Leet Speak Levels
357
+
358
+ | Level | Substitutions |
359
+ |-------|---------------|
360
+ | 1 (Basic) | a→@, e→3, i→1, o→0, s→$, t→7 |
361
+ | 2 (Extended) | + i→!, s→5 |
362
+ | 3 (Aggressive) | + a→4, l→1, b→8, g→9, h→# |
363
+
364
+ ### Hashcat Rule Support
365
+
366
+ Supported rule commands:
367
+
368
+ | Rule | Description | Example |
369
+ |------|-------------|--------|
370
+ | `l` | Lowercase all | `hello` → `hello` |
371
+ | `u` | Uppercase all | `hello` → `HELLO` |
372
+ | `c` | Capitalise first | `hello` → `Hello` |
373
+ | `s` | Swap case | `Hello` → `hELLO` |
374
+ | `r` | Reverse | `hello` → `olleh` |
375
+ | `d` | Duplicate whole word | `hi` → `hihi` |
376
+ | `p` | Duplicate first char | `hi` → `hhi` |
377
+ | `z` | Duplicate last char | `hi` → `hii` |
378
+ | `$X` | Append char X | `$!` → `pass!` |
379
+ | `^X` | Prepend char X | `^1` → `1pass` |
380
+ | `[N` | Keep first N chars | `[3` → `pas` |
381
+ | `]N` | Keep last N chars | `]3` → `ssw` |
382
+ | `iNX` | Insert char X at pos N | `i2X` → `paXssword` |
383
+ | `oNX` | Overwrite char at pos N with X | `o0X` → `Xassword` |
384
+ | `'XY` | Replace all X with Y | `'a@` → `p@ssword` |
385
+
386
+ ### Template Tokens
387
+
388
+ | Token | Resolves To |
389
+ |-------|-------------|
390
+ | `[FirstName]` | First name (original, Capitalised, UPPER, lower) |
391
+ | `[LastName]` | Last name |
392
+ | `[Nickname]` | Nickname |
393
+ | `[Pet]` | Pet name |
394
+ | `[Company]` | Company name |
395
+ | `[Color]` / `[Favourite_Color]` | Favourite colour |
396
+ | `[Partner]` | Partner's first name |
397
+ | `[Child]` / `[Children]` | Children's names |
398
+ | `[Keyword]` / `[Keywords]` | Keywords / interests |
399
+ | `[Year]` | 1986–current year |
400
+ | `[Year2]` | Two-digit years |
401
+ | `[Date]` | Birthdate from profile |
402
+ | `[Digit]` | 0–9 |
403
+ | `[Special]` | !@#$%^&*?._- |
404
+ | `[Upper]` | A–Z |
405
+ | `[Lower]` | a–z |
406
+ | `[Sep]` | Separators: _ - . @ # (empty) |
407
+ | `[123]` | 123, 1234, 12345, !@#, 1q2w3e |
408
+
409
+ Example: `[FirstName][Sep][Year]` with profile `firstname=John` generates:
410
+ `john_2024`, `john-2024`, `john.2024`, `John_2024`, `john@2024`, etc.
411
+
412
+ ---
413
+
414
+ ## Scoring & Filtering
415
+
416
+ ### zxcvbn Strength Scoring
417
+
418
+ When `--min-strength N` is provided (requires `zxcvbn` package), each candidate is scored on a 0–4 scale:
419
+
420
+ | Score | Strength | Description |
421
+ |-------|----------|-------------|
422
+ | 0 | Very Weak | Trivially guessable (e.g., `123456`) |
423
+ | 1 | Weak | Easily guessable (e.g., `password1`) |
424
+ | 2 | Fair | Moderately guessable |
425
+ | 3 | Strong | Uncommon but not resistant to targeted attacks |
426
+ | 4 | Very Strong | Highly resistant to cracking |
427
+
428
+ Candidates scoring below the threshold are pruned. This reduces wordlist size by removing trivially weak entries while keeping genuinely strong candidates.
429
+
430
+ ### Policy Filtering
431
+
432
+ Combine policy flags to enforce password complexity requirements:
433
+
434
+ ```bash
435
+ # At least 8 chars, one uppercase, one digit
436
+ pawpy -j profile.json --min-length 8 --require-upper --require-digit
437
+
438
+ # Complex: 10+ chars, mixed case, digit, special
439
+ pawpy -j profile.json --min-length 10 --require-upper --require-lower \
440
+ --require-digit --require-special
441
+ ```
442
+
443
+ ---
444
+
445
+ ## API & Dashboard
446
+
447
+ ### REST API
448
+
449
+ Start the API server:
450
+
451
+ ```bash
452
+ pawpy api
453
+ ```
454
+
455
+ Endpoints:
456
+
457
+ | Method | Path | Description |
458
+ |--------|------|-------------|
459
+ | GET | `/` | Health check |
460
+ | POST | `/generate` | Generate wordlist (multipart: profile JSON file + options) |
461
+ | GET | `/download/{job_id}` | Download generated wordlist |
462
+ | GET | `/jobs` | List all generation jobs |
463
+
464
+ Example with `curl`:
465
+
466
+ ```bash
467
+ curl -X POST http://127.0.0.1:8000/generate \
468
+ -F "profile=@target.json" \
469
+ -F "output=my_wordlist.txt" \
470
+ -F "extreme=true"
471
+ ```
472
+
473
+ ### Web Dashboard
474
+
475
+ ```bash
476
+ pawpy dashboard
477
+ # Open http://127.0.0.1:8080 in your browser
478
+ ```
479
+
480
+ The dashboard provides a dark-themed web interface where you can:
481
+
482
+ - Upload a profile JSON file
483
+ - Select generation mode (Normal / Lite / Extreme)
484
+ - Toggle Markov blending and zxcvbn scoring
485
+ - Monitor real-time generation progress via WebSocket
486
+ - Download the resulting wordlist
487
+
488
+ ---
489
+
490
+ ## OSINT Plugins
491
+
492
+ Pawpy includes a plugin system that auto-discovers Python modules in `pawpy/profile/plugins/`. Each plugin must define a `collect(profile: dict) -> dict` function that enriches the profile dict with OSINT-derived data.
493
+
494
+ ### Creating a Plugin
495
+
496
+ Create a new `.py` file in `pawpy/profile/plugins/`:
497
+
498
+ ```python
499
+ # pawpy/profile/plugins/my_plugin.py
500
+
501
+ from typing import Any, Dict
502
+
503
+
504
+ def collect(profile: Dict[str, Any]) -> Dict[str, Any]:
505
+ """Enrich profile with OSINT data."""
506
+ # Your OSINT logic here
507
+ # e.g., look up public social media profiles,
508
+ # check for breached credentials (with consent), etc.
509
+
510
+ if profile.get("firstname"):
511
+ keywords = profile.get("keywords", [])
512
+ if isinstance(keywords, str):
513
+ keywords = [keywords]
514
+ # Add OSINT-discovered keywords
515
+ keywords.append("discovered_keyword")
516
+ profile["keywords"] = keywords
517
+
518
+ return profile
519
+ ```
520
+
521
+ ### Important Rules for Plugin Authors
522
+
523
+ - **Respect rate-limiting** and terms of service of any external APIs or websites.
524
+ - **Only use OSINT data for authorised security testing.**
525
+ - **Follow responsible disclosure** practices.
526
+ - Handle exceptions gracefully so plugin failures don't crash the pipeline.
527
+
528
+ ---
529
+
530
+ ## Project Structure
531
+
532
+ ```
533
+ pawpy/
534
+ ├── pawpy/
535
+ │ ├── __init__.py # Package version and metadata
536
+ │ ├── __main__.py # python -m pawpy entry point
537
+ │ ├── cli.py # Full CLI with argparse
538
+ │ ├── config.py # PawpyConfig dataclass
539
+ │ ├── utils.py # Banner, logging, dedup, progress
540
+ │ ├── profile/
541
+ │ │ ├── __init__.py
542
+ │ │ ├── base.py # ProfileCollector (interactive + JSON)
543
+ │ │ ├── multi.py # Multi-target cross-referencing
544
+ │ │ └── plugins/
545
+ │ │ ├── __init__.py # Plugin discovery and loader
546
+ │ │ └── example.py # Example no-op plugin template
547
+ │ ├── mutations/
548
+ │ │ ├── __init__.py
549
+ │ │ ├── leet.py # Leet-speak (3 levels, combinatorial)
550
+ │ │ ├── dates.py # Date permutations (20+ variants)
551
+ │ │ ├── mangle.py # Common rules + hashcat rule engine
552
+ │ │ ├── markov.py # Markov chain training & generation
553
+ │ │ ├── keyboard.py # Static + dynamic keyboard walks
554
+ │ │ └── templates.py # Custom pattern template engine
555
+ │ ├── generator/
556
+ │ │ ├── __init__.py
557
+ │ │ ├── core.py # Main 15-stage pipeline orchestrator
558
+ │ │ ├── hybrid.py # Hybrid mask attacks (hashcat -a 6/7)
559
+ │ │ ├── sorter.py # Billion-scale external merge sort
560
+ │ │ └── gpu.py # Optional CuPy GPU acceleration
561
+ │ ├── scoring/
562
+ │ │ ├── __init__.py
563
+ │ │ └── scorer.py # zxcvbn-based strength pruning
564
+ │ ├── filters/
565
+ │ │ ├── __init__.py
566
+ │ │ └── policy.py # Password complexity policy filter
567
+ │ ├── api/
568
+ │ │ ├── __init__.py
569
+ │ │ ├── rest.py # FastAPI REST endpoints
570
+ │ │ └── dashboard.py # WebSocket web dashboard
571
+ │ └── data/
572
+ │ ├── __init__.py
573
+ │ ├── common_passwords.py # Embedded top 100 + SecLists loader
574
+ │ └── updater.py # Auto-update from SecLists
575
+ ├── tests/
576
+ │ ├── __init__.py
577
+ │ ├── test_leet.py
578
+ │ ├── test_dates.py
579
+ │ ├── test_mangle.py
580
+ │ ├── test_markov.py
581
+ │ ├── test_keyboard.py
582
+ │ ├── test_templates.py
583
+ │ ├── test_profile.py
584
+ │ ├── test_hybrid.py
585
+ │ └── test_policy.py
586
+ ├── .github/
587
+ │ └── workflows/
588
+ │ └── lint.yml # CI: flake8 + black + isort
589
+ ├── requirements.txt
590
+ ├── setup.py
591
+ └── README.md
592
+ ```
593
+
594
+ ---
595
+
596
+ ## Development
597
+
598
+ ### Setup
599
+
600
+ ```bash
601
+ git clone https://github.com/Danyalkhattak/pawpy.git
602
+ cd pawpy
603
+ pip install -e ".[all]"
604
+ pip install pytest
605
+ ```
606
+
607
+ ### Running Tests
608
+
609
+ ```bash
610
+ pytest tests/ -v
611
+ ```
612
+
613
+ ### Code Quality
614
+
615
+ ```bash
616
+ # Lint
617
+ flake8 pawpy/
618
+
619
+ # Format
620
+ black pawpy/
621
+ isort pawpy/
622
+
623
+ # All checks (also run by CI)
624
+ flake8 pawpy/ && black --check pawpy/ && isort --check-only pawpy/
625
+ ```
626
+
627
+ ### Adding a New Mutation
628
+
629
+ Create a new `.py` file in `pawpy/mutations/` with a function that takes a list of words and returns a list of mutated candidates:
630
+
631
+ ```python
632
+ # pawpy/mutations/my_mutation.py
633
+
634
+ def my_mutation(word: str) -> list[str]:
635
+ """Apply custom mutation to a word."""
636
+ return [word + "_custom", word.upper() + "123"]
637
+ ```
638
+
639
+ Then import and call it in `pawpy/generator/core.py` within the `PipelineOrchestrator.run()` method.
640
+
641
+ ---
642
+
643
+ ## Architecture & Data Flow
644
+
645
+ ```
646
+ User Input (CLI / JSON / API)
647
+
648
+
649
+ ┌─────────────────────┐
650
+ │ Profile Collection │ Interactive / JSON / OSINT Plugins
651
+ └──────────┬──────────┘
652
+
653
+
654
+ ┌─────────────────────┐
655
+ │ Base Word Extract │ All text fields → lowercase, deduplicated
656
+ │ + Date Extraction │
657
+ └──────────┬──────────┘
658
+
659
+
660
+ ┌──────────────────────────────────────────┐
661
+ │ Mutation Pipeline │
662
+ │ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
663
+ │ │ Leet │ │ Mangle │ │ Dates │ │
664
+ │ └──────────┘ └──────────┘ └───────────┘ │
665
+ │ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
666
+ │ │ Keyboard │ │ Markov │ │ Templates │ │
667
+ │ └──────────┘ └──────────┘ └───────────┘ │
668
+ │ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
669
+ │ │ Hybrid │ │ Rules │ │ Combos │ │
670
+ │ └──────────┘ └──────────┘ └───────────┘ │
671
+ └────────────────────┬─────────────────────┘
672
+
673
+
674
+ ┌──────────────────────────────────────────┐
675
+ │ Scoring & Filtering │
676
+ │ zxcvbn strength │ Policy compliance │
677
+ └────────────────────┬─────────────────────┘
678
+
679
+
680
+ ┌──────────────────────────────────────────┐
681
+ │ Sort + Deduplicate │
682
+ │ (in-memory or external merge sort) │
683
+ └────────────────────┬─────────────────────┘
684
+
685
+
686
+ Final Wordlist File
687
+ ```
688
+
689
+ ---
690
+
691
+ ## Performance Notes
692
+
693
+ - **Throughput**: On an 8-core CPU, the system targets ≥10 million passwords/minute for basic mutations.
694
+ - **Memory**: By default, stays under 2 GB RAM. For very large generation jobs, the external merge sorter handles disk-backed processing.
695
+ - **Output**: Written sequentially for optimal I/O. Sorted chunks are merge-sorted efficiently.
696
+ - **GPU**: Optional CuPy acceleration for rule application. Falls back gracefully to CPU if CuPy is not installed.
697
+
698
+ ---
699
+
700
+ ## License
701
+
702
+ MIT License. See [LICENSE](LICENSE) for details.
703
+
704
+ ---
705
+
706
+ ## Acknowledgements
707
+
708
+ - [CUPP](https://github.com/Mebus/cupp) – Original inspiration for interactive profiling
709
+ - [Hashcat](https://hashcat.net/wiki/doku.php?id=rule_based_attack) – Rule engine format
710
+ - [SecLists](https://github.com/danielmiessler/SecLists) – Common password data source
711
+ - [zxcvbn](https://github.com/dropbox/zxcvbn) – Password strength estimation
712
+ - [Rich](https://github.com/Textualize/rich) – Beautiful terminal output