pawpy-cli 1.0.0__tar.gz → 1.0.1__tar.gz
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.
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/PKG-INFO +1 -1
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/api/dashboard.py +11 -3
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/api/rest.py +14 -12
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/cli.py +2 -1
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy_cli.egg-info/PKG-INFO +1 -1
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pyproject.toml +1 -1
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/LICENSE +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/README.md +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/__init__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/__main__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/api/__init__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/config.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/data/__init__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/data/common_passwords.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/data/updater.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/filters/__init__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/filters/policy.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/generator/__init__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/generator/core.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/generator/gpu.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/generator/hybrid.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/generator/sorter.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/mutations/__init__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/mutations/dates.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/mutations/keyboard.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/mutations/leet.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/mutations/mangle.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/mutations/markov.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/mutations/templates.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/profile/__init__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/profile/base.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/profile/multi.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/profile/plugins/__init__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/profile/plugins/example.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/scoring/__init__.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/scoring/scorer.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy/utils.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy_cli.egg-info/SOURCES.txt +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy_cli.egg-info/dependency_links.txt +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy_cli.egg-info/entry_points.txt +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy_cli.egg-info/requires.txt +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/pawpy_cli.egg-info/top_level.txt +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/setup.cfg +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/tests/test_dates.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/tests/test_hybrid.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/tests/test_keyboard.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/tests/test_leet.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/tests/test_mangle.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/tests/test_markov.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/tests/test_policy.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/tests/test_profile.py +0 -0
- {pawpy_cli-1.0.0 → pawpy_cli-1.0.1}/tests/test_templates.py +0 -0
|
@@ -87,7 +87,7 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
|
|
|
87
87
|
</div>
|
|
88
88
|
</div>
|
|
89
89
|
<script>
|
|
90
|
-
const ws = new WebSocket(`ws
|
|
90
|
+
const ws = new WebSocket(`ws://127.0.0.1:8080/ws`);
|
|
91
91
|
ws.onmessage = (e) => {
|
|
92
92
|
const msg = JSON.parse(e.data);
|
|
93
93
|
const logArea = document.getElementById('logArea');
|
|
@@ -121,7 +121,7 @@ _DASHBOARD_HTML = """<!DOCTYPE html>
|
|
|
121
121
|
formData.append('min_strength', document.getElementById('scoring').checked ? '2' : '');
|
|
122
122
|
addLog('Starting generation...', 'info');
|
|
123
123
|
try {
|
|
124
|
-
const resp = await fetch('/generate', {
|
|
124
|
+
const resp = await fetch('http://127.0.0.1:8000/generate', {method: 'POST', body: formData});
|
|
125
125
|
const data = await resp.json();
|
|
126
126
|
if (data.download_url) {
|
|
127
127
|
addLog('Done! Download: ' + data.download_url, 'success');
|
|
@@ -177,7 +177,15 @@ def run_dashboard(host: str = "127.0.0.1", port: int = 8080):
|
|
|
177
177
|
@app.websocket("/ws")
|
|
178
178
|
async def websocket_endpoint(websocket: WebSocket):
|
|
179
179
|
await websocket.accept()
|
|
180
|
-
|
|
180
|
+
_connections.add(websocket)
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
while True:
|
|
184
|
+
await websocket.receive_text() # keep connection alive
|
|
185
|
+
except Exception:
|
|
186
|
+
_connections.discard(websocket)
|
|
187
|
+
finally:
|
|
188
|
+
_connections.discard(websocket)
|
|
181
189
|
|
|
182
190
|
logger.info("Starting Pawpy Dashboard on http://%s:%d", host, port)
|
|
183
191
|
uvicorn.run(app, host=host, port=port)
|
|
@@ -30,9 +30,10 @@ def get_app():
|
|
|
30
30
|
title="Pawpy API",
|
|
31
31
|
description="Educational Wordlist Generator – REST API",
|
|
32
32
|
version="1.0.0",
|
|
33
|
+
# ⚠️ optional safety switch if OpenAPI keeps crashing on Python 3.14
|
|
34
|
+
# openapi_url=None,
|
|
33
35
|
)
|
|
34
36
|
|
|
35
|
-
# In-memory job store (simple; production would use a database)
|
|
36
37
|
_jobs: Dict[str, Dict[str, Any]] = {}
|
|
37
38
|
|
|
38
39
|
@app.get("/")
|
|
@@ -50,13 +51,14 @@ def get_app():
|
|
|
50
51
|
markov: Annotated[bool, Form()] = False,
|
|
51
52
|
):
|
|
52
53
|
"""Generate a wordlist from an uploaded profile JSON file."""
|
|
54
|
+
|
|
53
55
|
job_id = str(uuid.uuid4())[:8]
|
|
54
56
|
out_file = output or f"pawpy_{job_id}.txt"
|
|
55
57
|
|
|
56
|
-
# Save uploaded profile to temp file
|
|
57
58
|
tmp_profile = tempfile.NamedTemporaryFile(
|
|
58
59
|
mode="w", suffix=".json", delete=False, prefix="pawpy_profile_"
|
|
59
60
|
)
|
|
61
|
+
|
|
60
62
|
content = await profile.read()
|
|
61
63
|
tmp_profile.write(content.decode("utf-8", errors="ignore"))
|
|
62
64
|
tmp_profile.close()
|
|
@@ -78,6 +80,7 @@ def get_app():
|
|
|
78
80
|
|
|
79
81
|
collector = ProfileCollector()
|
|
80
82
|
prof = collector.run(config)
|
|
83
|
+
|
|
81
84
|
orchestrator = PipelineOrchestrator(config, prof)
|
|
82
85
|
result_path = orchestrator.run()
|
|
83
86
|
|
|
@@ -101,6 +104,7 @@ def get_app():
|
|
|
101
104
|
status_code=500,
|
|
102
105
|
content={"job_id": job_id, "status": "error", "message": str(e)},
|
|
103
106
|
)
|
|
107
|
+
|
|
104
108
|
finally:
|
|
105
109
|
try:
|
|
106
110
|
os.unlink(tmp_profile.name)
|
|
@@ -109,12 +113,14 @@ def get_app():
|
|
|
109
113
|
|
|
110
114
|
@app.get("/download/{job_id}")
|
|
111
115
|
async def download_wordlist(job_id: str):
|
|
112
|
-
"""Download a generated wordlist by job ID."""
|
|
113
116
|
job = _jobs.get(job_id)
|
|
117
|
+
|
|
114
118
|
if not job or job["status"] != "completed":
|
|
115
119
|
return JSONResponse(
|
|
116
|
-
status_code=404,
|
|
120
|
+
status_code=404,
|
|
121
|
+
content={"error": "Job not found or not completed"},
|
|
117
122
|
)
|
|
123
|
+
|
|
118
124
|
return FileResponse(
|
|
119
125
|
job["output"],
|
|
120
126
|
media_type="text/plain",
|
|
@@ -123,7 +129,6 @@ def get_app():
|
|
|
123
129
|
|
|
124
130
|
@app.get("/jobs")
|
|
125
131
|
async def list_jobs():
|
|
126
|
-
"""List all generation jobs."""
|
|
127
132
|
return {"jobs": _jobs}
|
|
128
133
|
|
|
129
134
|
_app = app
|
|
@@ -131,13 +136,10 @@ def get_app():
|
|
|
131
136
|
|
|
132
137
|
|
|
133
138
|
def run_api(host: str = "127.0.0.1", port: int = 8000):
|
|
134
|
-
"""Start
|
|
139
|
+
"""Start API server."""
|
|
135
140
|
app = get_app()
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
raise ImportError(
|
|
140
|
-
"uvicorn is required for API mode. " "Install it with: pip install uvicorn"
|
|
141
|
-
)
|
|
141
|
+
|
|
142
|
+
import uvicorn
|
|
143
|
+
|
|
142
144
|
logger.info("Starting Pawpy API on %s:%d", host, port)
|
|
143
145
|
uvicorn.run(app, host=host, port=port)
|
|
@@ -8,6 +8,7 @@ api, dashboard).
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
10
|
import argparse
|
|
11
|
+
import asyncio
|
|
11
12
|
import logging
|
|
12
13
|
import sys
|
|
13
14
|
|
|
@@ -232,7 +233,7 @@ def handle_dashboard() -> None:
|
|
|
232
233
|
|
|
233
234
|
console.print("[cyan]Starting Pawpy Web Dashboard...[/cyan]")
|
|
234
235
|
try:
|
|
235
|
-
run_dashboard()
|
|
236
|
+
asyncio.run(run_dashboard())
|
|
236
237
|
except ImportError as e:
|
|
237
238
|
console.print(f"[red]Missing dependency:[/red] {e}")
|
|
238
239
|
sys.exit(1)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|