Skip to main content

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)
  • text
  • otpauth (TOTP provisioning URIs)

TOTP / OTPAuth

  • Generate RFC-compliant otpauth://totp URIs
  • 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 file
  • max_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

qrpypass-0.1.1.tar.gz (15.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qrpypass-0.1.1-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

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

Hashes for qrpypass-0.1.1.tar.gz
Algorithm Hash digest
SHA256 bd3a20d9a9284c1e82226309597da588e4d1d85233879de0098c47c061426432
MD5 b710947f6b53ce3c8e66fd162b59c7d9
BLAKE2b-256 179ff66ef4180aa250bf0d3f7aa7acab25bac51f7f3002e0a86b2c4185dec5f6

See more details on using hashes here.

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

Hashes for qrpypass-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 700f1433f000c288a2406b6df470d492c3bf6ebd4f5db64b12f20574071ee3f1
MD5 a6c7a385240c1085eebd2672955bba80
BLAKE2b-256 5a1bac0d125604cf78ddc02443edb94e6b656b8cef1dbb169d2209eadbf8bc6e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page