Skip to main content

Official LicenseChain Python SDK for license management and validation

Project description

LicenseChain Python SDK

License Python PyPI Downloads

Official Python SDK for LicenseChain - Secure license management for Python applications.

🚀 Features

  • 🔐 Secure Authentication - User registration, login, and session management
  • 📜 License Management - Create, validate, update, and revoke licenses
  • 🛡️ Hardware ID Validation - Prevent license sharing and unauthorized access
  • 🔔 Webhook Support - Real-time license events and notifications
  • 📊 Analytics Integration - Basic and advanced analytics with comprehensive metrics
  • 📦 Product Management - Create and manage products for license sales (Seller)
  • 👥 Team Collaboration - Team management and shared app/license access (Pro+)
  • ⚡ High Performance - Optimized for production workloads
  • 🔄 Async Operations - Non-blocking HTTP requests and data processing
  • 🛠️ Easy Integration - Simple API with comprehensive documentation

📦 Installation

Method 1: pip (Recommended)

# Install via pip
pip install licensechain-sdk

# Or with specific version
pip install licensechain-sdk==1.0.0

Method 2: pipenv

# Install via pipenv
pipenv install licensechain-sdk

Method 3: Poetry

# Install via Poetry
poetry add licensechain-sdk

Method 4: Manual Installation

  1. Download the latest release from GitHub Releases
  2. Extract to your project directory
  3. Install dependencies

🚀 Quick Start

Basic Setup

import asyncio
from licensechain import LicenseChainClient, LicenseChainConfig

async def main():
    # Initialize the client
    config = LicenseChainConfig(
        api_key="your-api-key",
        app_name="your-app-name",
        version="1.0.0"
    )
    
    client = LicenseChainClient(config)
    
    # Connect to LicenseChain
    try:
        await client.connect()
        print("Connected to LicenseChain successfully!")
    except Exception as e:
        print(f"Failed to connect: {e}")

if __name__ == "__main__":
    asyncio.run(main())

User Authentication

# Register a new user
try:
    user = await client.register("username", "password", "email@example.com")
    print("User registered successfully!")
    print(f"User ID: {user.id}")
except Exception as e:
    print(f"Registration failed: {e}")

# Login existing user
try:
    user = await client.login("username", "password")
    print("User logged in successfully!")
    print(f"Session ID: {user.session_id}")
except Exception as e:
    print(f"Login failed: {e}")

License Management

# Validate a license
try:
    license = await client.validate_license("LICENSE-KEY-HERE")
    print("License is valid!")
    print(f"License Key: {license.key}")
    print(f"Status: {license.status}")
    print(f"Expires: {license.expires}")
    print(f"Features: {', '.join(license.features)}")
    print(f"User: {license.user}")
except Exception as e:
    print(f"License validation failed: {e}")

# Get user's licenses
try:
    licenses = await client.get_user_licenses()
    print(f"Found {len(licenses)} licenses:")
    for i, license in enumerate(licenses):
        print(f"  {i + 1}. {license.key} - {license.status} (Expires: {license.expires})")
except Exception as e:
    print(f"Failed to get licenses: {e}")

Hardware ID Validation

# Get hardware ID (automatically generated)
hardware_id = client.get_hardware_id()
print(f"Hardware ID: {hardware_id}")

# Validate hardware ID with license
try:
    is_valid = await client.validate_hardware_id("LICENSE-KEY-HERE", hardware_id)
    if is_valid:
        print("Hardware ID is valid for this license!")
    else:
        print("Hardware ID is not valid for this license.")
except Exception as e:
    print(f"Hardware ID validation failed: {e}")

Webhook Integration

# Set up webhook handler
def webhook_handler(event, data):
    print(f"Webhook received: {event}")
    
    if event == "license.created":
        print(f"New license created: {data['licenseKey']}")
    elif event == "license.updated":
        print(f"License updated: {data['licenseKey']}")
    elif event == "license.revoked":
        print(f"License revoked: {data['licenseKey']}")

client.set_webhook_handler(webhook_handler)

# Start webhook listener
await client.start_webhook_listener()

📚 API Endpoints

All endpoints automatically use the /v1 prefix when connecting to https://api.licensechain.app.

Base URL

  • Production: https://api.licensechain.app/v1
  • Development: https://api.licensechain.app/v1

Available Endpoints

Method Endpoint Description
GET /v1/health Health check
POST /v1/auth/login User login
POST /v1/auth/register User registration
GET /v1/apps List applications
POST /v1/apps Create application
GET /v1/licenses List licenses
POST /v1/licenses/verify Verify license
GET /v1/webhooks List webhooks
POST /v1/webhooks Create webhook
GET /v1/analytics Get analytics

Note: The SDK automatically prepends /v1 to all endpoints, so you only need to specify the path (e.g., /auth/login instead of /v1/auth/login).

📚 API Reference

LicenseChainClient

Constructor

config = LicenseChainConfig(
    api_key="your-api-key",
    app_name="your-app-name",
    version="1.0.0",
    base_url="https://api.licensechain.app"  # Optional
)

client = LicenseChainClient(config)

Methods

Connection Management
# Connect to LicenseChain
await client.connect()

# Disconnect from LicenseChain
await client.disconnect()

# Check connection status
is_connected = client.is_connected()
User Authentication
# Register a new user
user = await client.register(username, password, email)

# Login existing user
user = await client.login(username, password)

# Logout current user
await client.logout()

# Get current user info
user = await client.get_current_user()
License Management
# Validate a license
license = await client.validate_license(license_key)

# Get user's licenses
licenses = await client.get_user_licenses()

# Create a new license
license = await client.create_license(user_id, features, expires)

# Update a license
license = await client.update_license(license_key, updates)

# Revoke a license
await client.revoke_license(license_key)

# Extend a license
license = await client.extend_license(license_key, days)
Hardware ID Management
# Get hardware ID
hardware_id = client.get_hardware_id()

# Validate hardware ID
is_valid = await client.validate_hardware_id(license_key, hardware_id)

# Bind hardware ID to license
await client.bind_hardware_id(license_key, hardware_id)
Webhook Management
# Set webhook handler
client.set_webhook_handler(handler)

# Start webhook listener
await client.start_webhook_listener()

# Stop webhook listener
await client.stop_webhook_listener()
Analytics
# Get basic dashboard insights (all tiers)
insights = await client.get_dashboard_insights()

# Get advanced analytics (Pro+ tier)
advanced = await client.get_advanced_analytics(
    start_date="2024-01-01",
    end_date="2024-12-31",
    metric="revenue"
)

# Get general analytics
analytics = await client.get_analytics(
    app_id="app_123",
    start_date="2024-01-01",
    end_date="2024-12-31"
)

# Get usage statistics
usage = await client.get_usage_stats(period="30d")

# Get license-specific analytics
license_analytics = await client.get_license_analytics("license_id")
Product Management (Seller only)
# List products
products = await client.list_products(
    limit=50,
    offset=0,
    active=True,
    search="Premium"
)

# Create a product
product = await client.create_product(
    name="Premium License",
    price=99.99,
    description="Premium license with all features",
    currency="USD",
    active=True
)

# Update a product
updated = await client.update_product(
    product_id="product_123",
    price=149.99,
    description="Updated description"
)

# Get product analytics
analytics = await client.get_product_analytics(product_id="product_123")

# Delete a product (if no licenses)
await client.delete_product("product_123")
Team Management (Pro+ tier)
# List teams
teams = await client.list_teams()

# Create a team
team = await client.create_team(
    name="Development Team",
    description="Team for development"
)

# Get team details
team_details = await client.get_team("team_123")

# Invite team member
await client.invite_team_member(
    team_id="team_123",
    email="member@example.com",
    role="member"  # owner, admin, or member
)

# List team members
members = await client.list_team_members("team_123")

# Update team member role
await client.update_team_member(
    team_id="team_123",
    member_id="member_123",
    role="admin"
)

# Remove team member
await client.remove_team_member("team_123", "member_123")

# Share app with team
await client.share_app_with_team("team_123", "app_123")

# List team apps
team_apps = await client.list_team_apps("team_123")

# Remove app from team
await client.remove_app_from_team("team_123", "app_123")

# Accept team invitation
await client.accept_team_invitation("team_123")

# Update team
await client.update_team(
    team_id="team_123",
    name="Updated Team Name",
    description="New description"
)

# Delete team (owner only)
await client.delete_team("team_123")

🔧 Configuration

Environment Variables

Set these in your environment or through your build process:

# Required
export LICENSECHAIN_API_KEY=your-api-key
export LICENSECHAIN_APP_NAME=your-app-name
export LICENSECHAIN_APP_VERSION=1.0.0

# Optional
export LICENSECHAIN_BASE_URL=https://api.licensechain.app
export LICENSECHAIN_DEBUG=true

Advanced Configuration

config = LicenseChainConfig(
    api_key="your-api-key",
    app_name="your-app-name",
    version="1.0.0",
    base_url="https://api.licensechain.app",
    timeout=30,        # Request timeout in seconds
    retries=3,         # Number of retry attempts
    debug=False,       # Enable debug logging
    user_agent="MyApp/1.0.0"  # Custom user agent
)

🛡️ Security Features

Hardware ID Protection

The SDK automatically generates and manages hardware IDs to prevent license sharing:

# Hardware ID is automatically generated and stored
hardware_id = client.get_hardware_id()

# Validate against license
is_valid = await client.validate_hardware_id(license_key, hardware_id)

Secure Communication

  • All API requests use HTTPS
  • API keys are securely stored and transmitted
  • Session tokens are automatically managed
  • Webhook signatures are verified

License Validation

  • Real-time license validation
  • Hardware ID binding
  • Expiration checking
  • Feature-based access control

📊 Analytics and Monitoring

Event Tracking

# Track custom events
await client.track_event("app.started", {
    "level": 1,
    "playerCount": 10
})

# Track license events
await client.track_event("license.validated", {
    "licenseKey": "LICENSE-KEY",
    "features": "premium,unlimited"
})

Performance Monitoring

# Get performance metrics
metrics = await client.get_performance_metrics()
print(f"API Response Time: {metrics.average_response_time}ms")
print(f"Success Rate: {metrics.success_rate:.2%}")
print(f"Error Count: {metrics.error_count}")

🔄 Error Handling

Custom Exception Types

try:
    license = await client.validate_license("invalid-key")
except InvalidLicenseError:
    print("License key is invalid")
except ExpiredLicenseError:
    print("License has expired")
except NetworkError as e:
    print(f"Network connection failed: {e}")
except LicenseChainError as e:
    print(f"LicenseChain error: {e}")

Retry Logic

# Automatic retry for network errors
config = LicenseChainConfig(
    api_key="your-api-key",
    app_name="your-app-name",
    version="1.0.0",
    retries=3,        # Retry up to 3 times
    timeout=30        # Wait 30 seconds for each request
)

🧪 Testing

Unit Tests

# Run tests
pytest

# Run tests with coverage
pytest --cov=licensechain

# Run specific test
pytest tests/test_client.py

Integration Tests

# Test with real API
pytest tests/integration/

📝 Examples

See the examples/ directory for complete examples:

  • basic_usage.py - Basic SDK usage
  • advanced_features.py - Advanced features and configuration
  • webhook_integration.py - Webhook handling

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

  1. Clone the repository
  2. Install Python 3.8 or later
  3. Install dependencies: pip install -r requirements.txt
  4. Build: python setup.py build
  5. Test: pytest

📄 License

This project is licensed under the Elastic 2.0 License - see the LICENSE file for details.

🆘 Support

🔗 Related Projects


Made with ❤️ for the Python community

PyPI Version Build Status Documentation Python Version

The official Python SDK for LicenseChain - a comprehensive license management platform. This SDK provides full API access for license validation, user management, application management, and more.

Features

  • License Management - Create, validate, update, and revoke licenses
  • User Authentication - Complete user management and authentication
  • Application Management - Manage applications and API keys
  • Webhook Support - Secure webhook verification and handling
  • Analytics - Access usage statistics and analytics
  • Error Handling - Comprehensive error handling with custom exceptions
  • Type Safety - Strong typing with Pydantic models
  • Async/Await - Full async support for all operations
  • Documentation - Comprehensive documentation and examples

Installation

pip

pip install licensechain-python-sdk

pipenv

pipenv install licensechain-python-sdk

poetry

poetry add licensechain-python-sdk

Quick Start

Basic Usage

import asyncio
from licensechain import LicenseChainClient

async def main():
    # Create a client
    client = LicenseChainClient("your_api_key_here")
    
    # Validate a license
    result = await client.validate_license("license_key_here")
    if result["valid"]:
        print("License is valid!")
        print(f"User: {result['user']['email']}")
        print(f"Expires: {result['expires_at']}")
    else:
        print(f"License is invalid: {result['error']}")
    
    # Create a new license
    license = await client.create_license(
        app_id="app_123",
        user_email="user@example.com",
        user_name="John Doe",
        expires_at="2024-12-31T23:59:59Z"
    )
    print(f"Created license: {license['key']}")
    
    # Close the client
    await client.close()

# Run the async function
asyncio.run(main())

Using the License Validator

import asyncio
from licensechain import LicenseValidator

async def main():
    # Create a validator instance
    validator = LicenseValidator("your_api_key_here")
    
    # Validate a license (returns ValidationResult object)
    result = await validator.validate_license("license_key_here")
    
    if result.valid:
        print("License is valid!")
        print(f"User: {result.user_email}")
        print(f"App: {result.app_name}")
        print(f"Features: {', '.join(result.features)}")
        print(f"Days until expiration: {result.days_until_expiration}")
    else:
        print(f"License is invalid: {result.error}")
    
    # Quick validation check
    if await validator.is_valid("license_key_here"):
        print("License is valid!")
    
    # Check if expired
    if await validator.is_expired("license_key_here"):
        print("License has expired!")
    
    # Close the validator
    await validator.close()

asyncio.run(main())

Using Context Managers

import asyncio
from licensechain import LicenseChainClient, LicenseValidator

async def main():
    # Using context managers for automatic cleanup
    async with LicenseChainClient("your_api_key_here") as client:
        result = await client.validate_license("license_key_here")
        print(f"Valid: {result['valid']}")
    
    async with LicenseValidator("your_api_key_here") as validator:
        is_valid = await validator.is_valid("license_key_here")
        print(f"Valid: {is_valid}")

asyncio.run(main())

API Reference

Client Methods

Authentication

# Register a new user
user = await client.register_user(
    email="user@example.com",
    password="secure_password",
    name="John Doe",
    company="Acme Corp"
)

# Login
session = await client.login(
    email="user@example.com",
    password="secure_password"
)

# Get user profile
profile = await client.get_user_profile()

# Update user profile
await client.update_user_profile({
    "name": "John Smith",
    "company": "New Company"
})

# Change password
await client.change_password(
    current_password="old_password",
    new_password="new_password"
)

# Password reset
await client.request_password_reset("user@example.com")
await client.reset_password(
    token="reset_token",
    new_password="new_password"
)

Application Management

# Create an application
app = await client.create_application(
    name="My App",
    description="A great application",
    webhook_url="https://myapp.com/webhooks",
    allowed_origins=["https://myapp.com"]
)

# List applications
apps = await client.list_applications(page=1, limit=20)

# Get application details
app = await client.get_application("app_123")

# Update application
await client.update_application("app_123", {
    "name": "Updated App Name",
    "description": "Updated description"
})

# Regenerate API key
new_key = await client.regenerate_api_key("app_123")

# Delete application
await client.delete_application("app_123")

License Management

# Create a license
license = await client.create_license(
    app_id="app_123",
    user_email="user@example.com",
    user_name="John Doe",
    expires_at="2024-12-31T23:59:59Z",
    metadata={"plan": "premium", "features": ["api_access"]}
)

# List licenses
licenses = await client.list_licenses(
    app_id="app_123",
    page=1,
    limit=20,
    status="active"
)

# Get license details
license = await client.get_license("lic_123")

# Update license
await client.update_license("lic_123", {
    "metadata": {"plan": "enterprise"}
})

# Validate license
result = await client.validate_license("license_key_here", app_id="app_123")

# Revoke license
await client.revoke_license("lic_123", reason="Violation of terms")

# Activate license
await client.activate_license("lic_123")

# Extend license
await client.extend_license("lic_123", "2025-12-31T23:59:59Z")

# Delete license
await client.delete_license("lic_123")

Webhook Management

# Create webhook
webhook = await client.create_webhook(
    app_id="app_123",
    url="https://myapp.com/webhooks",
    events=["license.created", "license.updated"],
    secret="webhook_secret"
)

# List webhooks
webhooks = await client.list_webhooks(app_id="app_123")

# Update webhook
await client.update_webhook("webhook_123", {
    "events": ["license.created", "license.updated", "license.revoked"]
})

# Test webhook
await client.test_webhook("webhook_123")

# Delete webhook
await client.delete_webhook("webhook_123")

Analytics

# Get analytics
analytics = await client.get_analytics(
    app_id="app_123",
    start_date="2024-01-01",
    end_date="2024-12-31",
    metric="validations"
)

# Get license analytics
license_analytics = await client.get_license_analytics("lic_123")

# Get usage statistics
usage = await client.get_usage_stats(app_id="app_123", period="30d")

Model Classes

The SDK provides Pydantic models for type safety and validation:

from licensechain import User, Application, License, ValidationResult

# User model
user = User(
    email="user@example.com",
    name="John Doe",
    company="Acme Corp"
)
print(user.is_active)

# Application model
app = Application(
    name="My App",
    description="A great application"
)
print(app.is_active)

# License model
license = License(
    app_id="app_123",
    user_email="user@example.com",
    expires_at="2024-12-31T23:59:59Z"
)
print(license.is_expired)
print(license.days_until_expiration)

# Validation result
result = ValidationResult(
    valid=True,
    user={"email": "user@example.com"},
    app={"name": "My App"}
)
print(result.user_email)
print(result.app_name)

Webhook Handling

from licensechain import WebhookHandler, WebhookVerifier

class MyWebhookHandler(WebhookHandler):
    async def handle_license_created(self, event_data):
        print(f"License created: {event_data['data']['id']}")
        return {"status": "processed"}
    
    async def handle_license_revoked(self, event_data):
        print(f"License revoked: {event_data['data']['id']}")
        return {"status": "processed"}

# Handle webhooks
handler = MyWebhookHandler("webhook_secret")
result = await handler.handle(payload, signature)

# Or verify signatures manually
verifier = WebhookVerifier("webhook_secret")
if verifier.verify_signature(payload, signature):
    data = verifier.parse_payload(payload, signature)
    print(f"Event: {data['type']}")

Error Handling

from licensechain import (
    LicenseChainException,
    AuthenticationError,
    ValidationError,
    NotFoundError,
    RateLimitError,
    ServerError,
    NetworkError
)

try:
    result = await client.validate_license("invalid_key")
except AuthenticationError as e:
    print(f"Authentication failed: {e}")
except ValidationError as e:
    print(f"Validation error: {e}")
except NotFoundError as e:
    print(f"Resource not found: {e}")
except RateLimitError as e:
    print(f"Rate limit exceeded: {e}")
except ServerError as e:
    print(f"Server error: {e}")
except NetworkError as e:
    print(f"Network error: {e}")
except LicenseChainException as e:
    print(f"LicenseChain error: {e}")

Configuration

Parameter Type Default Description
api_key str Required Your LicenseChain API key
base_url str https://api.licensechain.app API base URL
timeout int 30 Request timeout in seconds
retry_attempts int 3 Number of retry attempts
retry_delay float 1.0 Delay between retries in seconds

Error Types

Error Type HTTP Status Description
AuthenticationError 401, 403 Authentication or authorization failed
ValidationError 400 Invalid request data
NotFoundError 404 Resource not found
RateLimitError 429 Rate limit exceeded
ServerError 500-599 Server error
NetworkError N/A Network connectivity issues

Requirements

  • Python 3.8 or later
  • asyncio support
  • httpx for HTTP requests
  • pydantic for data validation

Dependencies

  • httpx>=0.24.0
  • pydantic>=2.0.0
  • typing-extensions>=4.5.0
  • requests>=2.31.0 (optional)
  • cryptography>=41.0.0 (optional)
  • python-dateutil>=2.8.0 (optional)

Development

# Clone the repository
git clone https://github.com/LicenseChain/LicenseChain-Python-SDK.git
cd LicenseChain-Python-SDK

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run linting
black licensechain/
isort licensechain/
flake8 licensechain/

# Build package
python -m build

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the Elastic License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by the LicenseChain team

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

licensechain_sdk-1.1.3.tar.gz (37.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

licensechain_sdk-1.1.3-py3-none-any.whl (35.3 kB view details)

Uploaded Python 3

File details

Details for the file licensechain_sdk-1.1.3.tar.gz.

File metadata

  • Download URL: licensechain_sdk-1.1.3.tar.gz
  • Upload date:
  • Size: 37.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for licensechain_sdk-1.1.3.tar.gz
Algorithm Hash digest
SHA256 a2c0bef1b96f3e3e7bbb318c852e3414ba6b50e4a4cac6e3d4b2789e0e9a5058
MD5 8e687301a216db8944b51f0f1dfea85d
BLAKE2b-256 97666856a53378aafde091ce3a6f9739150456bba006c695da60dfb5f103215e

See more details on using hashes here.

Provenance

The following attestation bundles were made for licensechain_sdk-1.1.3.tar.gz:

Publisher: ci.yml on LicenseChain/LicenseChain-Python-SDK

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file licensechain_sdk-1.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for licensechain_sdk-1.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 1371c5106f274d256b89f112004602c3641063f389d1d469d4bde1f67381c880
MD5 61336096cb2a9cf50c8306399ee12101
BLAKE2b-256 556f1cd1c91101d03c78879424aa1e94e0e3a01d5726c6073c2cea2ba6382723

See more details on using hashes here.

Provenance

The following attestation bundles were made for licensechain_sdk-1.1.3-py3-none-any.whl:

Publisher: ci.yml on LicenseChain/LicenseChain-Python-SDK

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page