Skip to content

Repository files navigation

LicenseChain Python SDK

LicensePythonPyPIDownloads

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

importasynciofromlicensechainimportLicenseChainClient, LicenseChainConfigasyncdefmain():
# Initialize the clientconfig=LicenseChainConfig(
api_key="your-api-key",
app_name="your-app-name",
version="1.0.0"
)
client=LicenseChainClient(config)
# Connect to LicenseChaintry:
awaitclient.connect()
print("Connected to LicenseChain successfully!")
exceptExceptionase:
print(f"Failed to connect: {e}")
if__name__=="__main__":
asyncio.run(main())

User Authentication

# Register a new usertry:
user=awaitclient.register("username", "password", "email@example.com")
print("User registered successfully!")
print(f"User ID: {user.id}")
exceptExceptionase:
print(f"Registration failed: {e}")
# Login existing usertry:
user=awaitclient.login("username", "password")
print("User logged in successfully!")
print(f"Session ID: {user.session_id}")
exceptExceptionase:
print(f"Login failed: {e}")

License Management

# Validate a licensetry:
license=awaitclient.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}")
exceptExceptionase:
print(f"License validation failed: {e}")
# Get user's licensestry:
licenses=awaitclient.get_user_licenses()
print(f"Found {len(licenses)} licenses:")
fori, licenseinenumerate(licenses):
print(f" {i+1}. {license.key} - {license.status} (Expires: {license.expires})")
exceptExceptionase:
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 licensetry:
is_valid=awaitclient.validate_hardware_id("LICENSE-KEY-HERE", hardware_id)
ifis_valid:
print("Hardware ID is valid for this license!")
else:
print("Hardware ID is not valid for this license.")
exceptExceptionase:
print(f"Hardware ID validation failed: {e}")

Webhook Integration

# Set up webhook handlerdefwebhook_handler(event, data):
print(f"Webhook received: {event}")
ifevent=="license.created":
print(f"New license created: {data['licenseKey']}")
elifevent=="license.updated":
print(f"License updated: {data['licenseKey']}")
elifevent=="license.revoked":
print(f"License revoked: {data['licenseKey']}")
client.set_webhook_handler(webhook_handler)
# Start webhook listenerawaitclient.start_webhook_listener()

📚 API Endpoints

Use the canonical API base URL https://api.licensechain.app/v1. The SDK also accepts the root host and normalizes requests to the same API version.

Base URL

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

Available Endpoints

MethodEndpointDescription
GET/v1/healthHealth check
POST/v1/auth/loginUser login
POST/v1/auth/registerUser registration
GET/v1/appsList applications
POST/v1/appsCreate application
GET/v1/licensesList licenses
POST/v1/licenses/verifyVerify license
GET/v1/webhooksList webhooks
POST/v1/webhooksCreate webhook
GET/v1/analyticsGet analytics

Note: The SDK accepts either the root host or the canonical /v1 base and normalizes endpoint requests automatically.

📚 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/v1"# Optional
)
client=LicenseChainClient(config)

Methods

Connection Management
# Connect to LicenseChainawaitclient.connect()
# Disconnect from LicenseChainawaitclient.disconnect()
# Check connection statusis_connected=client.is_connected()
User Authentication
# Register a new useruser=awaitclient.register(username, password, email)
# Login existing useruser=awaitclient.login(username, password)
# Logout current userawaitclient.logout()
# Get current user infouser=awaitclient.get_current_user()
License Management
# Validate a licenselicense=awaitclient.validate_license(license_key)
# Get user's licenseslicenses=awaitclient.get_user_licenses()
# Create a new licenselicense=awaitclient.create_license(user_id, features, expires)
# Update a licenselicense=awaitclient.update_license(license_key, updates)
# Revoke a licenseawaitclient.revoke_license(license_key)
# Extend a licenselicense=awaitclient.extend_license(license_key, days)
Hardware ID Management
# Get hardware IDhardware_id=client.get_hardware_id()
# Validate hardware IDis_valid=awaitclient.validate_hardware_id(license_key, hardware_id)
# Bind hardware ID to licenseawaitclient.bind_hardware_id(license_key, hardware_id)
Webhook Management
# Set webhook handlerclient.set_webhook_handler(handler)
# Start webhook listenerawaitclient.start_webhook_listener()
# Stop webhook listenerawaitclient.stop_webhook_listener()
Analytics
# Get basic dashboard insights (all tiers)insights=awaitclient.get_dashboard_insights()
# Get advanced analytics (Pro+ tier)advanced=awaitclient.get_advanced_analytics(
start_date="2024-01-01",
end_date="2024-12-31",
metric="revenue"
)
# Get general analyticsanalytics=awaitclient.get_analytics(
app_id="app_123",
start_date="2024-01-01",
end_date="2024-12-31"
)
# Get usage statisticsusage=awaitclient.get_usage_stats(period="30d")
# Get license-specific analyticslicense_analytics=awaitclient.get_license_analytics("license_id")
Product Management (Seller only)
# List productsproducts=awaitclient.list_products(
limit=50,
offset=0,
active=True,
search="Premium"
)
# Create a productproduct=awaitclient.create_product(
name="Premium License",
price=99.99,
description="Premium license with all features",
currency="USD",
active=True
)
# Update a productupdated=awaitclient.update_product(
product_id="product_123",
price=149.99,
description="Updated description"
)
# Get product analyticsanalytics=awaitclient.get_product_analytics(product_id="product_123")
# Delete a product (if no licenses)awaitclient.delete_product("product_123")
Team Management (Pro+ tier)
# List teamsteams=awaitclient.list_teams()
# Create a teamteam=awaitclient.create_team(
name="Development Team",
description="Team for development"
)
# Get team detailsteam_details=awaitclient.get_team("team_123")
# Invite team memberawaitclient.invite_team_member(
team_id="team_123",
email="member@example.com",
role="member"# owner, admin, or member
)
# List team membersmembers=awaitclient.list_team_members("team_123")
# Update team member roleawaitclient.update_team_member(
team_id="team_123",
member_id="member_123",
role="admin"
)
# Remove team memberawaitclient.remove_team_member("team_123", "member_123")
# Share app with teamawaitclient.share_app_with_team("team_123", "app_123")
# List team appsteam_apps=awaitclient.list_team_apps("team_123")
# Remove app from teamawaitclient.remove_app_from_team("team_123", "app_123")
# Accept team invitationawaitclient.accept_team_invitation("team_123")
# Update teamawaitclient.update_team(
team_id="team_123",
name="Updated Team Name",
description="New description"
)
# Delete team (owner only)awaitclient.delete_team("team_123")

🔧 Configuration

Environment Variables

Set these in your environment or through your build process:

# Requiredexport LICENSECHAIN_API_KEY=your-api-key
export LICENSECHAIN_APP_NAME=your-app-name
export LICENSECHAIN_APP_VERSION=1.0.0
# Optionalexport LICENSECHAIN_BASE_URL=https://api.licensechain.app/v1
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/v1",
timeout=30, # Request timeout in secondsretries=3, # Number of retry attemptsdebug=False, # Enable debug logginguser_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 storedhardware_id=client.get_hardware_id()
# Validate against licenseis_valid=awaitclient.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 eventsawaitclient.track_event("app.started", {
"level": 1,
"playerCount": 10
})
# Track license eventsawaitclient.track_event("license.validated", {
"licenseKey": "LICENSE-KEY",
"features": "premium,unlimited"
})

Performance Monitoring

# Get performance metricsmetrics=awaitclient.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=awaitclient.validate_license("invalid-key")
exceptInvalidLicenseError:
print("License key is invalid")
exceptExpiredLicenseError:
print("License has expired")
exceptNetworkErrorase:
print(f"Network connection failed: {e}")
exceptLicenseChainErrorase:
print(f"LicenseChain error: {e}")

Retry Logic

# Automatic retry for network errorsconfig=LicenseChainConfig(
api_key="your-api-key",
app_name="your-app-name",
version="1.0.0",
retries=3, # Retry up to 3 timestimeout=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
  • basic_analytics.py - Basic analytics features
  • advanced_analytics.py - Advanced analytics for Pro+ tiers
  • licenses_comprehensive.py - Comprehensive license management
  • products_example.py - Product management (Seller only)
  • teams_example.py - Team collaboration (Pro+ tiers)
  • secure_integration.py - Secure integration example preventing license bypassing
  • test_connection.py - Test script to verify SDK-API connection
  • test_licenses.py - Test script for validating specific license keys

Secure Integration Example

The secure_integration.py example demonstrates how to properly integrate LicenseChain SDK into your application to prevent license bypassing:

Key Features:

  • ✅ License validation on application startup
  • ✅ Periodic re-validation (configurable interval)
  • ✅ Hardware ID generation and validation
  • ✅ Critical operation protection
  • ✅ Secure state management with thread locks
  • ✅ Environment variables for sensitive data
  • ✅ Proper error handling and logging

Usage:

# Set environment variablesexport LICENSECHAIN_API_KEY='your-api-key'export LICENSECHAIN_LICENSE_KEY='your-license-key'export LICENSECHAIN_APP_ID='your-app-id'# Optional# Run the secure integration example
python examples/secure_integration.py

Key Implementation Points:

  1. Startup Validation: Always validate license when application starts
  2. Periodic Re-validation: Re-validate license at regular intervals
  3. Hardware ID Binding: Generate and validate hardware ID to prevent sharing
  4. Critical Operations: Protect critical operations with license checks
  5. Secure Storage: Never hardcode API keys or license keys

See examples/secure_integration.py for the complete implementation.

🤝 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 VersionBuild StatusDocumentationPython 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

importasynciofromlicensechainimportLicenseChainClientasyncdefmain():
# Create a clientclient=LicenseChainClient("your_api_key_here")
# Validate a licenseresult=awaitclient.validate_license("license_key_here")
ifresult["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 licenselicense=awaitclient.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 clientawaitclient.close()
# Run the async functionasyncio.run(main())

Using the License Validator

importasynciofromlicensechainimportLicenseValidatorasyncdefmain():
# Create a validator instancevalidator=LicenseValidator("your_api_key_here")
# Validate a license (returns ValidationResult object)result=awaitvalidator.validate_license("license_key_here")
ifresult.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 checkifawaitvalidator.is_valid("license_key_here"):
print("License is valid!")
# Check if expiredifawaitvalidator.is_expired("license_key_here"):
print("License has expired!")
# Close the validatorawaitvalidator.close()
asyncio.run(main())

Using Context Managers

importasynciofromlicensechainimportLicenseChainClient, LicenseValidatorasyncdefmain():
# Using context managers for automatic cleanupasyncwithLicenseChainClient("your_api_key_here") asclient:
result=awaitclient.validate_license("license_key_here")
print(f"Valid: {result['valid']}")
asyncwithLicenseValidator("your_api_key_here") asvalidator:
is_valid=awaitvalidator.is_valid("license_key_here")
print(f"Valid: {is_valid}")
asyncio.run(main())

API Reference

Client Methods

Authentication

# Register a new useruser=awaitclient.register_user(
email="user@example.com",
password="secure_password",
name="John Doe",
company="Acme Corp"
)
# Loginsession=awaitclient.login(
email="user@example.com",
password="secure_password"
)
# Get user profileprofile=awaitclient.get_user_profile()
# Update user profileawaitclient.update_user_profile({
"name": "John Smith",
"company": "New Company"
})
# Change passwordawaitclient.change_password(
current_password="old_password",
new_password="new_password"
)
# Password resetawaitclient.request_password_reset("user@example.com")
awaitclient.reset_password(
token="reset_token",
new_password="new_password"
)

Application Management

# Create an applicationapp=awaitclient.create_application(
name="My App",
description="A great application",
webhook_url="https://myapp.com/webhooks",
allowed_origins=["https://myapp.com"]
)
# List applicationsapps=awaitclient.list_applications(page=1, limit=20)
# Get application detailsapp=awaitclient.get_application("app_123")
# Update applicationawaitclient.update_application("app_123", {
"name": "Updated App Name",
"description": "Updated description"
})
# Regenerate API keynew_key=awaitclient.regenerate_api_key("app_123")
# Delete applicationawaitclient.delete_application("app_123")

License Management

# Create a licenselicense=awaitclient.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 licenseslicenses=awaitclient.list_licenses(
app_id="app_123",
page=1,
limit=20,
status="active"
)
# Get license detailslicense=awaitclient.get_license("lic_123")
# Update licenseawaitclient.update_license("lic_123", {
"metadata": {"plan": "enterprise"}
})
# Validate licenseresult=awaitclient.validate_license("license_key_here", app_id="app_123")
# Revoke licenseawaitclient.revoke_license("lic_123", reason="Violation of terms")
# Activate licenseawaitclient.activate_license("lic_123")
# Extend licenseawaitclient.extend_license("lic_123", "2025-12-31T23:59:59Z")
# Delete licenseawaitclient.delete_license("lic_123")

Webhook Management

# Create webhookwebhook=awaitclient.create_webhook(
app_id="app_123",
url="https://myapp.com/webhooks",
events=["license.created", "license.updated"],
secret="webhook_secret"
)
# List webhookswebhooks=awaitclient.list_webhooks(app_id="app_123")
# Update webhookawaitclient.update_webhook("webhook_123", {
"events": ["license.created", "license.updated", "license.revoked"]
})
# Test webhookawaitclient.test_webhook("webhook_123")
# Delete webhookawaitclient.delete_webhook("webhook_123")

Analytics

# Get analyticsanalytics=awaitclient.get_analytics(
app_id="app_123",
start_date="2024-01-01",
end_date="2024-12-31",
metric="validations"
)
# Get license analyticslicense_analytics=awaitclient.get_license_analytics("lic_123")
# Get usage statisticsusage=awaitclient.get_usage_stats(app_id="app_123", period="30d")

Model Classes

The SDK provides Pydantic models for type safety and validation:

fromlicensechainimportUser, Application, License, ValidationResult# User modeluser=User(
email="user@example.com",
name="John Doe",
company="Acme Corp"
)
print(user.is_active)
# Application modelapp=Application(
name="My App",
description="A great application"
)
print(app.is_active)
# License modellicense=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 resultresult=ValidationResult(
valid=True,
user={"email": "user@example.com"},
app={"name": "My App"}
)
print(result.user_email)
print(result.app_name)

Webhook Handling

fromlicensechainimportWebhookHandler, WebhookVerifierclassMyWebhookHandler(WebhookHandler):
asyncdefhandle_license_created(self, event_data):
print(f"License created: {event_data['data']['id']}")
return {"status": "processed"}
asyncdefhandle_license_revoked(self, event_data):
print(f"License revoked: {event_data['data']['id']}")
return {"status": "processed"}
# Handle webhookshandler=MyWebhookHandler("webhook_secret")
result=awaithandler.handle(payload, signature)
# Or verify signatures manuallyverifier=WebhookVerifier("webhook_secret")
ifverifier.verify_signature(payload, signature):
data=verifier.parse_payload(payload, signature)
print(f"Event: {data['type']}")

Error Handling

fromlicensechainimport (
LicenseChainException,
AuthenticationError,
ValidationError,
NotFoundError,
RateLimitError,
ServerError,
NetworkError
)
try:
result=awaitclient.validate_license("invalid_key")
exceptAuthenticationErrorase:
print(f"Authentication failed: {e}")
exceptValidationErrorase:
print(f"Validation error: {e}")
exceptNotFoundErrorase:
print(f"Resource not found: {e}")
exceptRateLimitErrorase:
print(f"Rate limit exceeded: {e}")
exceptServerErrorase:
print(f"Server error: {e}")
exceptNetworkErrorase:
print(f"Network error: {e}")
exceptLicenseChainExceptionase:
print(f"LicenseChain error: {e}")

Configuration

ParameterTypeDefaultDescription
api_keystrRequiredYour LicenseChain API key
base_urlstrhttps://api.licensechain.app/v1API base URL
timeoutint30Request timeout in seconds
retry_attemptsint3Number of retry attempts
retry_delayfloat1.0Delay between retries in seconds

Error Types

Error TypeHTTP StatusDescription
AuthenticationError401, 403Authentication or authorization failed
ValidationError400Invalid request data
NotFoundError404Resource not found
RateLimitError429Rate limit exceeded
ServerError500-599Server error
NetworkErrorN/ANetwork 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 (ELv2) — see the LICENSE file for details.

Support


Made with ❤️ by the LicenseChain team

LicenseChain API (v1)

This SDK targets the LicenseChain HTTP API v1 implemented by the LicenseChain API service.

  • Production base URL:https://api.licensechain.app/v1
  • API reference:docs.licensechain.app
  • Baseline REST mapping (documented for integrators):
    • GET /health
    • POST /auth/register
    • POST /licenses/verify
    • PATCH /licenses/:id/revoke
    • PATCH /licenses/:id/activate
    • PATCH /licenses/:id/extend
    • GET /analytics/stats

About

Official Python SDK for LicenseChain — license validation and management

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages