API Documentation
/
Backend
/
Python
/
Integrate in Existing Python Project

Integrate in Existing Python Project

Add Hawcx authentication to an existing Python application

Integrating Hawcx Backend SDK into Existing Python Projects

This guide walks through adding Hawcx OAuth authentication to an existing Python backend.

Step 1: Install the SDK

pip install hawcx-oauth-client

Step 2: Set Up Environment Variables

Create a .env file or configure your environment with:

# Config ID (public identifier)
HAWCX_API_KEY=your_config_id
# Optional base URL override
HAWCX_BASE_URL=https://api.hawcx.com

# Optional (for delegation / MFA management)
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

Step 3: Create an Exchange Endpoint

Create a new route to handle Hawcx code exchange:

from hawcx_oauth_client import HawcxOAuth
from flask import Blueprint, request, jsonify
import os

auth_bp = Blueprint('auth', __name__)

oauth = HawcxOAuth(
    config_id=os.getenv('HAWCX_API_KEY'),
    base_url=os.getenv('HAWCX_BASE_URL')
)

@auth_bp.route('/exchange', methods=['POST'])
def exchange():
    try:
        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

        result = oauth.exchange_code(auth_code, code_verifier)
        claims = result.claims

        # Find or create user in your database
        user = find_or_create_user({
            'id': claims['sub'],
            'email': claims.get('email')
        })

        # Create your application's session/JWT
        session_token = generate_session_token(user)

        return jsonify({
            'success': True,
            'sessionToken': session_token,
            'user': {
                'id': user.id,
                'email': user.email
            }
        })
    except Exception as error:
        print(f'Hawcx exchange error: {error}')
        return jsonify({'error': 'Authentication failed'}), 401

Step 4: Integrate with Your User Management

Update your user service to handle Hawcx identities:

# services/user_service.py
from db import session
from models import User

class HawcxUser:
    def __init__(self, id: str, email: str | None):
        self.id = id
        self.email = email

def find_or_create_user(hawcx_user: HawcxUser):
    user = session.query(User).filter_by(hawcx_id=hawcx_user.id).first()

    if not user:
        user = User(hawcx_id=hawcx_user.id, email=hawcx_user.email)
        session.add(user)
        session.commit()

    return user

Optional: Backend-Driven MFA Management

If you need to manage MFA from your backend, use the delegation client with your keys:

from hawcx_oauth_client.delegation import HawcxDelegationClient, MfaMethod
import os

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')
)

result = client.initiate_mfa_change(
    userid='[email protected]',
    mfa_method=MfaMethod.SMS,
    phone_number='+15551234567'
)

client.verify_mfa_change(
    userid='[email protected]',
    session_id=result['session_id'],
    otp='123456'
)