Headless QR decoder + TOTP authenticator Flask mini-service
Project description
qr-pypass
qr-pypass is a local-first, headless QR decoding and TOTP service designed for security workflows, air-gapped environments, and automation pipelines.
It is built to reliably decode real-world QR codes such as phone screenshots, camera photos, cropped images, and distorted captures — without cloud APIs, mobile devices, or external services.
The project now uses state-of-the-art QR detection via OpenCV’s WeChat QR detector, which significantly outperforms legacy ZXing-style decoders on modern smartphone imagery.
Homepage: https://ginkorea.one Source: https://github.com/ginkorea/qr-pypass PyPI: https://pypi.org/project/qrpypass/
Why qr-pypass Exists
Most QR libraries work well only for:
• perfectly cropped QR codes • synthetic QR images • ideal lighting and contrast
They often fail on:
• phone screenshots • camera photos • skewed or rotated QRs • partial codes • high-resolution images
qr-pypass is designed for the messiness of reality.
It was built for red teams, blue teams, labs, SOC tooling, and automation where QR and 2FA artifacts need to be decoded locally and reliably.
Core Capabilities
QR Detection and Decoding
-
WeChat QR detector (OpenCV contrib) — primary engine
-
Detects multiple QR codes per image
-
Handles:
- screenshots
- camera photos
- large images
- rotated or skewed QRs
-
Returns:
- decoded payload
- bounding box
- corner points
- detection method used
WeChat QR is now the first-pass detector and succeeds on cases where older approaches fail.
Payload Classification
Decoded payloads are automatically classified as:
urltextotpauth(RFC-compliant TOTP provisioning URIs)
This allows direct routing into downstream automation or security workflows.
TOTP / OTPAuth Support
- Generate RFC-6238 compliant TOTP secrets
- Import existing
otpauth://totpURIs - Store secrets locally (optionally encrypted at rest)
- Generate current TOTP codes
- Verify TOTP codes with configurable time drift
This enables headless authenticator workflows without phones or apps.
QR Generation
Generate QR codes for:
- URLs
- arbitrary text
- TOTP provisioning URIs
Options include:
- configurable box size
- configurable border
- PNG output
HTTP Service + Minimal UI
qr-pypass exposes:
- a Python API
- a Flask-based HTTP service
- a minimal web UI
No JavaScript frameworks. No external assets. No cloud calls.
Installation
From PyPI
pip install qrpypass
Python 3.9+ required.
From Source (Development)
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 .
Running the Service
python -m qrpypass.service.run
Default address:
http://127.0.0.1:5000
Configuration
Environment variables:
| Variable | Default | Description |
|---|---|---|
QRPYPASS_HOST |
127.0.0.1 |
Bind address |
QRPYPASS_PORT |
5000 |
Port |
QRPYPASS_DEBUG |
0 |
Flask debug mode |
QRPYPASS_QR_DEBUG |
0 |
QR detection debug logging |
QRPYPASS_STORE_DIR |
~/.qrpypass |
Local TOTP storage |
Web UI Routes
/— QR scan UI (upload screenshots or photos)/gen— payload and QR generator/vault— TOTP account management
HTTP API Overview
Health Check
GET /health
Scan QR Codes
POST /scan
Content-Type: multipart/form-data
Form fields
file(required)max_results(optional, default: 8)
Returns structured detection results including bounding boxes.
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 accounts |
GET /auth/code |
Get current code |
POST /auth/verify |
Verify code |
Optional passphrase enables encryption at rest.
Python API Example
from qrpypass.qr import scan_and_classify
hits = scan_and_classify("screenshot.png")
for hit in hits:
print(hit.classification.kind, hit.qr.payload)
Testing
Included end-to-end tests:
python test/api-test.py
python test/full_api_smoke.py
python test/test_totp_verify_flow.py
Covers:
- QR generation → scan → classification
- TOTP generation, import, code, and verification
Security Model
- No outbound network access
- Secrets never logged
- Optional encryption at rest
- Designed for offline and air-gapped use
Common Use Cases
- Extract QR payloads from screenshots
- Analyze phishing or 2FA enrollment flows
- Headless TOTP verification
- Red-team and blue-team labs
- Offline QR decoding pipelines
- Mobile-free authenticator replacement
License
MIT
Author
Josh Gompert https://ginkorea.one
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.2.3.tar.gz.
File metadata
- Download URL: qrpypass-0.2.3.tar.gz
- Upload date:
- Size: 26.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dca10665a66eb89ac65b8f92b069bf6a6c012cba35aead055211e4f1bbc8a7b7
|
|
| MD5 |
fa677458d381a2afc6f492775babcca2
|
|
| BLAKE2b-256 |
10a4306ab6b35bdb8fe4951dd043864a32a46976e03eeb894f3ea1aab2d3fda4
|
File details
Details for the file qrpypass-0.2.3-py3-none-any.whl.
File metadata
- Download URL: qrpypass-0.2.3-py3-none-any.whl
- Upload date:
- Size: 28.4 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 |
8f9951050f0ee0487bf32fa99652886412c0065a88a0b670d2d61d2fdc3a7a91
|
|
| MD5 |
bff69696009f9c25f77223ac4d4a7a67
|
|
| BLAKE2b-256 |
860d82ce6449e7e112142a1d72fcccabea29d37fc50aebf797454200dd69af12
|