Official Python SDK for QRAuth — cryptographic QR code verification
Project description
qrauth
Official Python SDK for QRAuth -- cryptographic QR code verification and anti-fraud infrastructure.
Install
pip install qrauth
Quick Start
from qrauth import QRAuth
qr = QRAuth(api_key="qrauth_xxx")
# Generate a verified QR code
code = qr.create(
"https://municipal-parking.com/pay",
location={"lat": 40.63, "lng": 22.94},
expires_in="1y",
)
print(code["verification_url"])
# -> https://qrauth.io/v/xK9m2pQ7
# Verify a scanned QR code
result = qr.verify("xK9m2pQ7")
print(result["verified"]) # True
print(result["security"]["trustScore"]) # 94
API
QRAuth(api_key=None, *, client_id=None, client_secret=None, base_url="https://qrauth.io")
At least one of api_key or client_id must be provided.
| Parameter | Type | Description |
|---|---|---|
api_key |
str |
API key (starts with qrauth_). Required for QR management calls |
client_id |
str |
App client ID (starts with qrauth_app_). Required for auth sessions |
client_secret |
str |
App client secret. Required alongside client_id |
base_url |
str |
API base URL. Defaults to https://qrauth.io |
qr.create(destination, **kwargs)
Generate a cryptographically signed QR code.
code = qr.create(
"https://example.com/pay",
label="Parking Meter #42",
location={"lat": 40.63, "lng": 22.94, "radiusM": 100},
expires_in="30d",
)
| Parameter | Type | Description |
|---|---|---|
destination |
str |
Target URL |
label |
str |
Human-readable label |
location |
dict |
{"lat": ..., "lng": ..., "radiusM": ...} geo-fence |
expires_in |
str |
Duration (30s, 5m, 6h, 30d, 1y) or ISO date |
content_type |
str |
Content type: url, event, coupon, vcard, etc. |
content |
dict |
Structured content (for non-URL types) |
qr.verify(token, *, client_lat=None, client_lng=None)
Verify a QR code and get its trust score.
result = qr.verify("xK9m2pQ7", client_lat=40.63, client_lng=22.94)
qr.list(*, page=1, page_size=20, status=None)
List QR codes for your organization.
response = qr.list(page=1, page_size=20, status="ACTIVE")
for item in response["data"]:
print(item["token"], item["status"])
qr.get(token)
Get details of a specific QR code.
qr.revoke(token)
Revoke a QR code so it no longer verifies.
qr.bulk(items)
Create up to 64 QR codes in a single request.
result = qr.bulk([
{"destination": "https://example.com/1", "label": "Meter 1"},
{"destination": "https://example.com/2", "label": "Meter 2"},
])
QR-Based Authentication (Auth Sessions)
Use auth sessions to let users authenticate on your site by scanning a QR code with the QRAuth app.
Requires an App client_id and client_secret (configured in your QRAuth dashboard).
QRAuth(client_id, client_secret, *, base_url="https://qrauth.io")
from qrauth import QRAuth
qr = QRAuth(client_id="qrauth_app_xxx", client_secret="your_secret")
You can combine both modes in a single instance:
qr = QRAuth(
api_key="qrauth_xxx",
client_id="qrauth_app_xxx",
client_secret="your_secret",
)
qr.create_auth_session(**kwargs) → AuthSessionResponse
Create a new auth session. Display session["qr_url"] as a QR code for the user to scan.
session = qr.create_auth_session(scopes=["identity", "email"])
print(session["qr_url"]) # encode this as a QR code
print(session["session_id"]) # use to poll status
| Parameter | Type | Description |
|---|---|---|
scopes |
list[str] |
Requested scopes (e.g. ["identity", "email"]) |
redirect_url |
str |
URL to redirect after approval (deep-link flows) |
metadata |
dict |
Arbitrary metadata attached to the session |
code_challenge |
str |
PKCE code challenge (S256). Required for public clients |
code_challenge_method |
str |
Code challenge method. Only "S256" is supported |
qr.get_auth_session(session_id, *, code_verifier=None) → AuthSessionStatus
Poll the session status. Call this on an interval (e.g. every 2 seconds) until
status is "APPROVED", "DENIED", or "EXPIRED".
import time
while True:
status = qr.get_auth_session(session["session_id"])
if status["status"] == "APPROVED":
print(status["user"]) # {"id": "...", "name": "...", "email": "..."}
break
if status["status"] in ("DENIED", "EXPIRED"):
break
time.sleep(2)
qr.verify_auth_result(session_id, signature) → AuthSessionVerifyResult
Verify the approved session on your backend. Call this after your frontend
receives onSuccess from the browser SDK to confirm the session is genuine
before issuing your own session or JWT.
result = qr.verify_auth_result(session_id, signature)
if result["valid"]:
user = result["session"]["user"]
# issue your own session for the user
Full flow example
from qrauth import QRAuth
import time
qr = QRAuth(client_id="qrauth_app_xxx", client_secret="your_secret")
# 1. Create session and show QR code to user
session = qr.create_auth_session(scopes=["identity", "email"])
print(f"Scan this URL: {session['qr_url']}")
# 2. Poll until resolved
while True:
s = qr.get_auth_session(session["session_id"])
if s["status"] == "APPROVED":
break
if s["status"] in ("DENIED", "EXPIRED"):
raise Exception("Auth failed")
time.sleep(2)
# 3. Verify on the backend
result = qr.verify_auth_result(session["session_id"], s["signature"])
if result["valid"]:
print(result["session"]["user"]) # log in the user
Context Manager
The client can be used as a context manager to ensure the HTTP connection pool is properly closed:
with QRAuth(api_key="qrauth_xxx") as qr:
code = qr.create("https://example.com")
Error Handling
from qrauth import QRAuth, AuthenticationError, RateLimitError
try:
qr.create("https://example.com")
except AuthenticationError:
print("Bad API key")
except RateLimitError as err:
print(f"Rate limited. Retry after {err.retry_after}s")
| Exception | HTTP Status | Description |
|---|---|---|
ValidationError |
400 | Request validation failed |
AuthenticationError |
401 | Invalid or missing API key |
AuthorizationError |
403 | Insufficient permissions |
NotFoundError |
404 | Resource not found |
RateLimitError |
429 | Rate limit exceeded |
QuotaExceededError |
429 | Plan quota exceeded |
QRAuthError |
* | Base class for all errors |
License
MIT
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 qrauth-0.3.0.tar.gz.
File metadata
- Download URL: qrauth-0.3.0.tar.gz
- Upload date:
- Size: 14.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e199855f92f7f14d57b862c9bc10541ed604260fa31b5f77e50323fde710058f
|
|
| MD5 |
3d882711a4287b0c8f2c73d0444f5b48
|
|
| BLAKE2b-256 |
61b5ae2eebc20c755dbd4098ad38c57c61157cd6ebacedafc133470d6e6d2f41
|
File details
Details for the file qrauth-0.3.0-py3-none-any.whl.
File metadata
- Download URL: qrauth-0.3.0-py3-none-any.whl
- Upload date:
- Size: 16.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9dd8244e431ac99db2a63d77d740e5aa5e1bc8311638dcdf9958937a6a7d8f5
|
|
| MD5 |
beeb05e4f0d8923897b6fa208ba7cc30
|
|
| BLAKE2b-256 |
8a33ffaf53e2d96f2f2db85a8d7e10110e2495d34c64061bf5181f137e4ecea7
|