Headless QR decoder + TOTP authenticator Flask mini-service
Project description
qr-pypass
qr-pypass is a lightweight, headless QR decoding and TOTP authentication service.
It is designed for air-gapped labs, automation pipelines, and security tooling where you need to:
- Decode QR codes from screenshots or images
- Classify QR payloads (URL, text, otpauth)
- Generate QR codes programmatically
- Generate, import, store, and verify TOTP (RFC 6238) secrets
- Run everything locally with no cloud dependencies
The project exposes both a Python API and a Flask-based HTTP service with a minimal web UI.
Features
QR Decoding
- Detects multiple QR codes anywhere in an image
- Uses OpenCV with multi-pass detection and tiling fallback
- Returns bounding boxes, corners, and decode method
- Robust against screenshots, partial QRs, and large images
Payload Classification
Automatically classifies decoded QR payloads as:
url(with normalization)textotpauth(TOTP provisioning URIs)
TOTP / OTPAuth
- Generate RFC-compliant
otpauth://totpURIs - Import existing provisioning URIs
- Secure local storage (optional encryption at rest)
- Generate current TOTP codes
- Verify TOTP codes with configurable window
QR Generation
- Generate QR codes for:
- URLs
- Arbitrary text
- TOTP provisioning URIs
- Control box size and border
- Returns PNG images
Service + UI
- Flask API
- Minimal web UI for:
- Uploading screenshots
- Viewing decoded QR payloads
- Generating QR codes
- Managing TOTP accounts
Installation
git clone https://github.com/ginkorea/qr-pypass.git
cd qr-pypass
python -m venv .qr-env
source .qr-env/bin/activate
pip install -r requirements.txt
pip install -e .
Python 3.9+ is required.
Running the Service
python -m qrpypass.service.run
By default the service runs on:
http://127.0.0.1:5000
Environment Variables
| Variable | Default | Description |
|---|---|---|
QRPYPASS_HOST |
127.0.0.1 |
Bind address |
QRPYPASS_PORT |
5000 |
Port |
QRPYPASS_DEBUG |
0 |
Enable Flask debug |
QRPYPASS_STORE_DIR |
~/.qrpypass |
Account storage directory |
Web UI
/– QR scan UI (upload screenshots/images)/gen– QR payload + TOTP generator
No JavaScript frameworks, no external assets.
API Overview
Health Check
GET /health
Scan QR Codes
POST /scan
Content-Type: multipart/form-data
Form fields
file(required) – image filemax_results(optional, default: 8)
Generate Payload
POST /gen/payload
Content-Type: application/json
{
"kind": "url | text | totp",
"params": { ... },
"import": false,
"passphrase": null
}
Generate QR Image
POST /gen/qr
Content-Type: application/json
{
"payload": "...",
"box_size": 8,
"border": 2
}
Returns image/png.
TOTP Endpoints
| Endpoint | Description |
|---|---|
POST /auth/import |
Import otpauth URI |
GET /auth/list |
List stored accounts |
GET /auth/code |
Get current TOTP code |
POST /auth/verify |
Verify TOTP code |
Optional passphrase encrypts the store at rest.
Python API Example
from qrpypass.qr import scan_and_classify
hits = scan_and_classify("screenshot.png")
for h in hits:
print(h.classification.kind, h.qr.payload)
Testing
End-to-end API tests are included:
python test/api-test.py
python test/full_api_smoke.py
python test/test_totp_verify_flow.py
These tests cover:
- QR generation → scan → classification
- TOTP generation, import, code generation, and verification
Security Notes
- Secrets are never logged
- TOTP store can be encrypted using a passphrase
- No outbound network access
- Suitable for air-gapped or lab environments
Use Cases
- QR extraction from screenshots (2FA enrollment, phishing analysis)
- Headless TOTP verification in security tooling
- Red-team / blue-team labs
- Offline QR decoding pipelines
- Lightweight local alternative to mobile authenticator apps
License
MIT
Author
Josh Gompert
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qrpypass-0.1.1.tar.gz.
File metadata
- Download URL: qrpypass-0.1.1.tar.gz
- Upload date:
- Size: 15.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd3a20d9a9284c1e82226309597da588e4d1d85233879de0098c47c061426432
|
|
| MD5 |
b710947f6b53ce3c8e66fd162b59c7d9
|
|
| BLAKE2b-256 |
179ff66ef4180aa250bf0d3f7aa7acab25bac51f7f3002e0a86b2c4185dec5f6
|
File details
Details for the file qrpypass-0.1.1-py3-none-any.whl.
File metadata
- Download URL: qrpypass-0.1.1-py3-none-any.whl
- Upload date:
- Size: 16.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
700f1433f000c288a2406b6df470d492c3bf6ebd4f5db64b12f20574071ee3f1
|
|
| MD5 |
a6c7a385240c1085eebd2672955bba80
|
|
| BLAKE2b-256 |
5a1bac0d125604cf78ddc02443edb94e6b656b8cef1dbb169d2209eadbf8bc6e
|