Tutorial

Python SDK for License Management: Integrate Traffic Orchestrator in Minutes

TOT
Traffic Orchestrator Team
Engineering
March 19, 2026 10 min read 461 words
Share

Python powers everything from web apps (Django, Flask, FastAPI) to CLI tools, data pipelines, and desktop applications. Each has different licensing needs. Here's how to integrate Traffic Orchestrator's license validation across the Python ecosystem.

Quick Start: REST API Validation

The simplest integration — one HTTP call to validate a license key:

import requests

def validate_license(key: str, domain: str) -> dict:
    response = requests.post(
        "https://api.trafficorchestrator.com/api/v1/validate",
        json={"key": key, "domain": domain},
        timeout=5
    )
    return response.json()

result = validate_license("TO-PRO-XXXX-XXXX-XXXX", "app.customer.com")
if result.get("valid"):
    print(f"License valid until {result['expiresAt']}")
else:
    print("License invalid — features restricted")

Django: Middleware-Based Licensing

Protect entire Django apps or specific views with middleware:

# middleware/licensing.py
from django.http import JsonResponse
from django.conf import settings
import requests

class LicenseMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.cached_result = None
        self.cache_ttl = 3600  # Re-validate every hour

    def __call__(self, request):
        if not self._is_license_valid():
            return JsonResponse(
                {"error": "License expired or invalid"},
                status=402
            )
        return self.get_response(request)

    def _is_license_valid(self):
        # Use cached result if fresh
        if self.cached_result and not self.cached_result.expired:
            return self.cached_result.valid

        result = requests.post(
            "https://api.trafficorchestrator.com/api/v1/validate",
            json={
                "key": settings.LICENSE_KEY,
                "domain": settings.ALLOWED_HOSTS[0]
            }
        ).json()

        self.cached_result = CachedResult(result, ttl=self.cache_ttl)
        return result.get("valid", False)

Flask: Decorator Pattern

Use a decorator to gate specific Flask routes:

from functools import wraps
from flask import jsonify, current_app

def require_license(feature=None):
    def decorator(f):
        @wraps(f)
        def decorated(*args, **kwargs):
            result = validate_license(
                current_app.config["LICENSE_KEY"],
                current_app.config["SERVER_NAME"]
            )
            if not result.get("valid"):
                return jsonify(error="License required"), 402
            if feature and feature not in result.get("features", []):
                return jsonify(error=f"Feature '{feature}' requires upgrade"), 402
            return f(*args, **kwargs)
        return decorated
    return decorator

# Usage
@app.route("/api/reports")
@require_license(feature="analytics")
def reports():
    return jsonify(data=generate_report())

FastAPI: Dependency Injection

from fastapi import Depends, HTTPException

async def verify_license(feature: str = None):
    result = validate_license(
        settings.LICENSE_KEY,
        settings.DOMAIN
    )
    if not result.get("valid"):
        raise HTTPException(status_code=402, detail="License required")
    if feature and feature not in result.get("features", []):
        raise HTTPException(status_code=402, detail=f"{feature} requires upgrade")
    return result

@app.get("/api/insights")
async def insights(license=Depends(lambda: verify_license("insights"))):
    return {"data": generate_insights()}

CLI Tools: Activation Flow

For command-line tools, implement a one-time activation that stores the validated key locally:

import json, os
from pathlib import Path

CONFIG_DIR = Path.home() / ".myapp"
LICENSE_FILE = CONFIG_DIR / "license.json"

def activate(key: str):
    result = validate_license(key, "cli.myapp.com")
    if result.get("valid"):
        CONFIG_DIR.mkdir(exist_ok=True)
        LICENSE_FILE.write_text(json.dumps(result))
        print("License activated successfully")
    else:
        print("Invalid license key")

def check_license() -> bool:
    if LICENSE_FILE.exists():
        data = json.loads(LICENSE_FILE.read_text())
        # Re-validate periodically
        return data.get("valid", False)
    return False

Best Practices

  • Cache validation results — Don't call the API on every request. Cache for 1-24 hours.
  • Handle network failures gracefully — If the API is unreachable, use the cached result with a grace period.
  • Never hardcode keys — Use environment variables or config files.
  • Log validation events — Track when licenses validate, expire, or fail for debugging.

Getting Started

Traffic Orchestrator's REST API works with any Python HTTP library. Pick the integration pattern that matches your framework, add your license key to your environment, and start validating in under 5 minutes.

TOT
Traffic Orchestrator Team
Engineering

The engineering team behind Traffic Orchestrator, building enterprise-grade software licensing infrastructure used by developers worldwide.

Was this article helpful?
Get licensing insights delivered

Engineering deep-dives, security advisories, and product updates. Unsubscribe anytime.

Share this article
Free Plan Available

Ship licensing in your next release

5 licenses, 500 validations/month, full API access. Set up in under 5 minutes — no credit card required.

2-minute setup No credit card Cancel anytime