Python Backend SDK Quickstart
Integrate Hawcx OAuth authentication in your Python backend
Hawcx OAuth Client SDK for Python
Add passwordless authentication to your Python backend. Exchange authorization codes for verified user claims and manage MFA.
Installation
pip install hawcx-oauth-clientQuick Start
OAuth Code Exchange
The most common flow: exchange authCode + codeVerifier for verified user claims.
from hawcx_oauth_client import HawcxOAuth
from flask import request, jsonify
import os
oauth = HawcxOAuth(
config_id=os.getenv('HAWCX_API_KEY'),
base_url=os.getenv('HAWCX_BASE_URL') # optional
)
@app.route('/exchange', methods=['POST'])
def exchange():
try:
data = request.json
result = oauth.exchange_code(data['authCode'], data['codeVerifier'])
claims = result.claims
# Create user session or JWT
return jsonify({
'success': True,
'userId': claims['sub'],
'email': claims.get('email')
})
except Exception as error:
app.logger.error(f'Authentication failed: {error}')
return jsonify({'error': 'Authentication failed'}), 401Hawcx Delegation Client (MFA Setup)
For advanced use cases like setting up MFA for users programmatically:
from hawcx_oauth_client.delegation import HawcxDelegationClient, MfaMethod
import os
# Initialize the delegation client with your signing/encryption keys
client = HawcxDelegationClient.from_keys(
sp_signing_key=os.getenv('SP_ED25519_PRIVATE_KEY_PEM'),
sp_encryption_key=os.getenv('SP_X25519_PRIVATE_KEY_PEM'),
idp_verify_key=os.getenv('IDP_ED25519_PUBLIC_KEY_PEM'),
idp_encryption_key=os.getenv('IDP_X25519_PUBLIC_KEY_PEM'),
base_url=os.getenv('HAWCX_BASE_URL') or 'https://api.hawcx.com',
sp_id=os.getenv('OAUTH_CLIENT_ID')
)
# Initiate MFA setup (Email, SMS, or TOTP)
result = client.initiate_mfa_change(
userid='[email protected]',
mfa_method=MfaMethod.SMS,
phone_number='+15551234567'
)
# Verify OTP and complete MFA setup
client.verify_mfa_change(
userid='[email protected]',
session_id=result['session_id'],
otp='123456'
)
# Get user credentials
creds = client.get_user_credentials('[email protected]')
print(f"MFA method: {creds.get('mfa_method')}")Configuration
Environment Variables
For OAuth Code Exchange:
# Config ID (public identifier)
HAWCX_API_KEY="your-config-id"
# Optional base URL override
HAWCX_BASE_URL="https://api.hawcx.com"For Hawcx Delegation:
SP_ED25519_PRIVATE_KEY_PEM="-----BEGIN PRIVATE KEY-----..."
SP_X25519_PRIVATE_KEY_PEM="-----BEGIN PRIVATE KEY-----..."
IDP_ED25519_PUBLIC_KEY_PEM="-----BEGIN PUBLIC KEY-----..."
IDP_X25519_PUBLIC_KEY_PEM="-----BEGIN PUBLIC KEY-----..."
OAUTH_CLIENT_ID="your-client-id"Integration Examples
Flask
from flask import Flask, request, jsonify, session
from hawcx_oauth_client import HawcxOAuth
import os
app = Flask(__name__)
app.secret_key = os.getenv('FLASK_SECRET_KEY')
oauth = HawcxOAuth(config_id=os.getenv('HAWCX_API_KEY'))
@app.route('/exchange', methods=['POST'])
def exchange():
data = request.json
auth_code = data.get('authCode')
code_verifier = data.get('codeVerifier')
if not auth_code or not code_verifier:
return jsonify({'error': 'Missing authCode or codeVerifier'}), 400
try:
result = oauth.exchange_code(auth_code, code_verifier)
claims = result.claims
session['user_id'] = claims['sub']
session['email'] = claims.get('email')
return jsonify({'success': True, 'userId': claims['sub']})
except Exception as error:
app.logger.error(f'Authentication failed: {error}')
return jsonify({'error': 'Authentication failed'}), 401Django
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from hawcx_oauth_client import HawcxOAuth
import os
oauth = HawcxOAuth(config_id=os.getenv('HAWCX_API_KEY'))
@require_http_methods(["POST"])
def exchange(request):
auth_code = request.POST.get('authCode')
code_verifier = request.POST.get('codeVerifier')
if not auth_code or not code_verifier:
return JsonResponse({'error': 'Missing authCode or codeVerifier'}, status=400)
try:
result = oauth.exchange_code(auth_code, code_verifier)
claims = result.claims
request.session['user_id'] = claims['sub']
request.session['email'] = claims.get('email')
return JsonResponse({'success': True, 'userId': claims['sub']})
except Exception:
return JsonResponse({'error': 'Authentication failed'}, status=401)FastAPI
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from hawcx_oauth_client import HawcxOAuth
import os
app = FastAPI()
oauth = HawcxOAuth(config_id=os.getenv('HAWCX_API_KEY'))
@app.post('/exchange')
async def exchange(payload: dict):
auth_code = payload.get('authCode')
code_verifier = payload.get('codeVerifier')
if not auth_code or not code_verifier:
return JSONResponse({'error': 'Missing authCode or codeVerifier'}, status_code=400)
try:
result = oauth.exchange_code(auth_code, code_verifier)
claims = result.claims
return JSONResponse({
'success': True,
'userId': claims['sub'],
'email': claims.get('email')
})
except Exception:
return JSONResponse({'error': 'Authentication failed'}, status_code=401)PKCE Support
codeVerifier is required for the exchange. Store it on the client and send it alongside authCode when your backend calls exchange_code().
Next Steps
- View the complete API reference for advanced features and detailed method signatures
- Set up MFA management for your users
- Join our developer community on Slack for support and updates