QuantumLockβ’ Integration Guide
Complete Guide for Integrating QuantumLockβ’ into Your Applicationβ
This guide covers all aspects of integrating QuantumLockβ’ licensing into your software products.
π― Integration Overviewβ
Architectureβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β YOUR APPLICATION ARCHITECTURE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββββββ ββββββββββββββββββββ β
β β Your Backend ββββββ API Key ββββββΆβ QuantumLockβ’ β β
β β (License Gen) β β API β β
β ββββββββββ¬ββββββββββ ββββββββββββββββββββ β
β β β
β β License File β
β βΌ β
β ββββββββββββββββββββ ββββββββββββββββββββ β
β β Your Client ββββ Validation βββββΆβ QuantumLockβ’ β β
β β Application β (optional) β Validator β β
β ββββββββββββββββββββ ββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π§ Integration Methodsβ
Method 1: Server-Side Generation + Client Validationβ
Best for: Desktop applications, on-premise software
# === YOUR BACKEND (License Generation) ===
from quantumlock.sdk import QuantumLockClient
client = QuantumLockClient(api_key=os.environ["QUANTUMLOCK_API_KEY"])
@app.post("/api/licenses/create")
def create_license_for_customer(customer_email: str, plan: str):
# Map your plans to QuantumLock features
features = {
"free": ["basic"],
"pro": ["basic", "premium", "api_access"],
"enterprise": ["basic", "premium", "api_access", "enterprise", "unlimited"]
}
license = client.generate_license(
end_customer_id=customer_email,
features=features[plan],
valid_days=365
)
# Send license to customer via email or download
return {"license_file": license}
# === YOUR CLIENT APPLICATION (Validation) ===
from quantumlock.sdk import LicenseValidator
class MyApp:
def __init__(self):
self.validator = LicenseValidator()
def startup(self):
license_path = self.find_license_file()
if not self.validator.validate(license_path):
self.show_license_dialog()
return False
return True
@self.validator.require_feature("premium")
def premium_feature(self):
# This only runs if "premium" is in the license
pass
Method 2: API-Only (SaaS Applications)β
Best for: Web applications, SaaS products
from quantumlock.sdk import QuantumLockClient
from functools import wraps
client = QuantumLockClient(api_key=os.environ["QUANTUMLOCK_API_KEY"])
# Store license keys in your database
class User(db.Model):
email = db.Column(db.String)
quantumlock_license = db.Column(db.String)
def require_valid_license(f):
@wraps(f)
def decorated(*args, **kwargs):
user = get_current_user()
# Validate with QuantumLock API
result = client.validate_license(
license_key=user.quantumlock_license,
end_customer_id=user.email
)
if not result["valid"]:
return {"error": "Invalid license"}, 403
# Attach features to request context
g.features = result["features"]
return f(*args, **kwargs)
return decorated
@app.get("/api/premium/data")
@require_valid_license
def get_premium_data():
if "premium" not in g.features:
return {"error": "Premium required"}, 403
return {"data": "premium content"}
Method 3: Hybrid (Online + Offline)β
Best for: Applications that may work offline
from quantumlock.sdk import LicenseValidator, QuantumLockClient
class HybridValidator:
def __init__(self):
self.offline_validator = LicenseValidator()
self.online_client = QuantumLockClient(
api_key=os.environ.get("QUANTUMLOCK_API_KEY")
)
def validate(self, license_path: str, customer_id: str) -> dict:
# First: Quick offline check
if not self.offline_validator.validate(license_path):
return {"valid": False, "reason": "Invalid signature"}
# Get cached license info
info = self.offline_validator.get_license_info()
# Try online validation if API key available
if self.online_client.api_key:
try:
online_result = self.online_client.validate_license(
license_key=info["license_key"],
end_customer_id=customer_id
)
# Check if license was revoked
if not online_result["valid"]:
return {"valid": False, "reason": online_result["message"]}
except ConnectionError:
# Offline mode - trust local validation
pass
return {
"valid": True,
"features": info["features"],
"expires": info["valid_until"]
}
π± Platform-Specific Integrationβ
FastAPIβ
from fastapi import FastAPI, Depends, HTTPException, Security
from fastapi.security import APIKeyHeader
from quantumlock.sdk import LicenseValidator
app = FastAPI()
validator = LicenseValidator(license_path="/etc/app/license.lic")
# Validate on startup
@app.on_event("startup")
async def validate_app_license():
if not validator.validate():
raise RuntimeError("Application license is invalid!")
# Feature-based dependency
def require_feature(feature: str):
def checker():
if not validator.has_feature(feature):
raise HTTPException(status_code=403, detail=f"Feature '{feature}' not licensed")
return Depends(checker)
@app.get("/api/basic")
async def basic_endpoint():
return {"status": "ok"}
@app.get("/api/analytics", dependencies=[require_feature("analytics")])
async def analytics_endpoint():
return {"analytics": "data"}
Flaskβ
from flask import Flask, g, abort
from functools import wraps
from quantumlock.sdk import LicenseValidator
app = Flask(__name__)
validator = LicenseValidator(license_path="./license.lic")
@app.before_first_request
def check_license():
if not validator.validate():
raise RuntimeError("License invalid")
def require_feature(feature):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not validator.has_feature(feature):
abort(403, description=f"Feature '{feature}' not licensed")
return f(*args, **kwargs)
return decorated_function
return decorator
@app.route('/api/premium')
@require_feature('premium')
def premium_endpoint():
return {'data': 'premium'}
Djangoβ
# middleware.py
from django.http import JsonResponse
from quantumlock.sdk import LicenseValidator
class LicenseMiddleware:
validator = LicenseValidator(license_path="/etc/app/license.lic")
validated = False
def __init__(self, get_response):
self.get_response = get_response
if not self.validated:
if not self.validator.validate():
raise RuntimeError("License invalid")
self.validated = True
def __call__(self, request):
# Attach validator to request
request.license = self.validator
return self.get_response(request)
# decorators.py
from functools import wraps
from django.http import HttpResponseForbidden
def require_feature(feature):
def decorator(view_func):
@wraps(view_func)
def wrapped(request, *args, **kwargs):
if not request.license.has_feature(feature):
return HttpResponseForbidden(f"Feature '{feature}' not licensed")
return view_func(request, *args, **kwargs)
return wrapped
return decorator
# views.py
@require_feature('premium')
def premium_view(request):
return JsonResponse({'data': 'premium'})
CLI Applications (Click)β
import click
from quantumlock.sdk import LicenseValidator, LicenseError
validator = LicenseValidator()
def require_license(f):
@click.pass_context
def wrapper(ctx, *args, **kwargs):
license_path = ctx.obj.get('license') or '~/.myapp/license.lic'
try:
if not validator.validate(license_path):
click.echo("β License invalid or expired", err=True)
ctx.exit(1)
except LicenseError as e:
click.echo(f"β License error: {e}", err=True)
ctx.exit(1)
return f(*args, **kwargs)
return wrapper
@click.group()
@click.option('--license', help='Path to license file')
@click.pass_context
def cli(ctx, license):
ctx.ensure_object(dict)
ctx.obj['license'] = license
@cli.command()
@require_license
def run():
"""Run the application"""
click.echo("β Running with valid license")
@cli.command()
@require_license
def premium_command():
"""Premium feature"""
if not validator.has_feature('premium'):
click.echo("β Premium license required", err=True)
return
click.echo("β Premium feature executed")
π License Lifecycle Managementβ
Generating Licenses (Your Backend)β
from quantumlock.sdk import QuantumLockClient
client = QuantumLockClient(api_key=os.environ["QUANTUMLOCK_API_KEY"])
# When customer purchases/upgrades
def on_customer_purchase(customer_email: str, plan: str, months: int):
license = client.generate_license(
end_customer_id=customer_email,
features=get_features_for_plan(plan),
valid_days=months * 30,
metadata={
"plan": plan,
"purchase_date": datetime.now().isoformat()
}
)
# Store in your database
save_license_to_db(customer_email, license)
# Send to customer
send_license_email(customer_email, license)
return license
Renewal Flowβ
def on_subscription_renewal(customer_email: str):
# Generate new license with extended validity
new_license = client.generate_license(
end_customer_id=customer_email,
features=get_current_features(customer_email),
valid_days=365
)
# Optionally revoke old license
old_license_key = get_old_license_key(customer_email)
if old_license_key:
# Old license will naturally expire, but you can revoke immediately
pass
return new_license
Upgrade/Downgradeβ
def on_plan_change(customer_email: str, new_plan: str):
# Revoke old license (optional - can let it expire)
old_key = get_customer_license_key(customer_email)
# Generate new license with new features
new_license = client.generate_license(
end_customer_id=customer_email,
features=get_features_for_plan(new_plan),
valid_days=get_remaining_days(customer_email)
)
return new_license
β Best Practicesβ
DOβ
- Store API key securely - Use environment variables or secrets manager
- Validate on startup - Check license when application starts
- Cache validation results - Avoid calling API on every request
- Handle offline gracefully - Fall back to offline validation
- Log license events - For audit and troubleshooting
- Use feature flags - Map QuantumLock features to your feature flags
DON'Tβ
- Don't expose API key - Never in frontend or client code
- Don't hardcode licenses - Always load from secure storage
- Don't trust client time - Use server time for expiry checks
- Don't skip validation - Always validate before granting access
- Don't cache indefinitely - Refresh validation periodically
π Supportβ
Need help with integration?
- Email: support@softquantus.com
- Portal: https://portal.softquantus.com
- Documentation: https://docs.softquantus.com
Β© 2025 SoftQuantus. All rights reserved.