273 lines
6.2 KiB
Markdown
273 lines
6.2 KiB
Markdown
# IronLicensing SDK for Python
|
|
|
|
Software licensing and activation SDK for Python applications. Validate licenses, manage activations, check features, and handle trials.
|
|
|
|
[](https://pypi.org/project/ironlicensing/)
|
|
[](https://pypi.org/project/ironlicensing/)
|
|
[](https://opensource.org/licenses/MIT)
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
pip install ironlicensing
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### Validate a License
|
|
|
|
```python
|
|
import ironlicensing
|
|
|
|
# Initialize
|
|
ironlicensing.init("pk_live_xxxxx", "my-app")
|
|
|
|
# Validate a license key
|
|
result = ironlicensing.validate("IRON-XXXX-XXXX-XXXX-XXXX")
|
|
|
|
if result.valid:
|
|
print("License is valid!")
|
|
print(f"Expires: {result.license.expires_at}")
|
|
```
|
|
|
|
### Activate a License
|
|
|
|
```python
|
|
import ironlicensing
|
|
|
|
ironlicensing.init("pk_live_xxxxx", "my-app")
|
|
|
|
# Activate on this machine
|
|
result = ironlicensing.activate("IRON-XXXX-XXXX-XXXX-XXXX")
|
|
|
|
if result.valid:
|
|
print("License activated!")
|
|
print(f"Activations: {len(result.activations)}")
|
|
```
|
|
|
|
### Check Features
|
|
|
|
```python
|
|
import ironlicensing
|
|
from ironlicensing import LicenseRequiredError
|
|
|
|
ironlicensing.init("pk_live_xxxxx", "my-app")
|
|
ironlicensing.validate("IRON-XXXX-XXXX-XXXX-XXXX")
|
|
|
|
# Check if feature is enabled
|
|
if ironlicensing.has_feature("premium"):
|
|
# Enable premium features
|
|
pass
|
|
|
|
# Or require a feature (raises if not available)
|
|
try:
|
|
ironlicensing.require_feature("enterprise")
|
|
# Enterprise code here
|
|
except LicenseRequiredError:
|
|
print("Enterprise license required")
|
|
```
|
|
|
|
### Async Support
|
|
|
|
```python
|
|
import asyncio
|
|
import ironlicensing
|
|
|
|
async def main():
|
|
ironlicensing.init("pk_live_xxxxx", "my-app")
|
|
|
|
# Async validation
|
|
result = await ironlicensing.validate_async("IRON-XXXX-XXXX-XXXX-XXXX")
|
|
|
|
# Async activation
|
|
result = await ironlicensing.activate_async("IRON-XXXX-XXXX-XXXX-XXXX")
|
|
|
|
# Async trial
|
|
result = await ironlicensing.start_trial_async("user@example.com")
|
|
|
|
asyncio.run(main())
|
|
```
|
|
|
|
### Using the Client Directly
|
|
|
|
```python
|
|
from ironlicensing import LicenseClient, LicenseOptions
|
|
|
|
client = LicenseClient(LicenseOptions(
|
|
public_key="pk_live_xxxxx",
|
|
product_slug="my-app",
|
|
debug=True,
|
|
))
|
|
|
|
# Validate
|
|
result = client.validate("IRON-XXXX-XXXX-XXXX-XXXX")
|
|
|
|
# Check features
|
|
if client.has_feature("premium"):
|
|
pass
|
|
|
|
# Clean up
|
|
client.close()
|
|
```
|
|
|
|
## Configuration
|
|
|
|
```python
|
|
from ironlicensing import LicenseClient, LicenseOptions
|
|
|
|
client = LicenseClient(LicenseOptions(
|
|
public_key="pk_live_xxxxx", # Required
|
|
product_slug="my-app", # Required
|
|
api_base_url="https://api.ironlicensing.com",
|
|
debug=False,
|
|
enable_offline_cache=True,
|
|
cache_validation_minutes=60,
|
|
offline_grace_days=7,
|
|
storage_key_prefix="ironlicensing",
|
|
))
|
|
```
|
|
|
|
### Configuration Options
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `public_key` | str | required | Your public key (pk_live_xxx or pk_test_xxx) |
|
|
| `product_slug` | str | required | Your product slug |
|
|
| `api_base_url` | str | https://api.ironlicensing.com | API base URL |
|
|
| `debug` | bool | False | Enable debug logging |
|
|
| `enable_offline_cache` | bool | True | Cache validation results |
|
|
| `cache_validation_minutes` | int | 60 | Cache validity in minutes |
|
|
| `offline_grace_days` | int | 7 | Offline grace period in days |
|
|
|
|
## License Status
|
|
|
|
```python
|
|
LicenseStatus = Literal[
|
|
"valid", # License is valid
|
|
"expired", # License has expired
|
|
"suspended", # License is suspended
|
|
"revoked", # License is revoked
|
|
"invalid", # License key is invalid
|
|
"trial", # Trial license
|
|
"trial_expired", # Trial has expired
|
|
"not_activated", # No license activated
|
|
"unknown", # Unknown status
|
|
]
|
|
```
|
|
|
|
## Features
|
|
|
|
### Check Features
|
|
|
|
```python
|
|
# Check if feature is enabled
|
|
if client.has_feature("premium"):
|
|
enable_premium_features()
|
|
|
|
# Get feature details
|
|
feature = client.get_feature("max-users")
|
|
if feature and feature.enabled:
|
|
print(f"Max users: {feature.metadata.get('limit')}")
|
|
|
|
# Get all features
|
|
for f in client.get_features():
|
|
print(f"{f.name}: {'enabled' if f.enabled else 'disabled'}")
|
|
```
|
|
|
|
### Require Features
|
|
|
|
```python
|
|
from ironlicensing import LicenseRequiredError
|
|
|
|
try:
|
|
client.require_feature("enterprise")
|
|
# This code only runs if feature is available
|
|
except LicenseRequiredError:
|
|
show_upgrade_dialog()
|
|
```
|
|
|
|
## Trial Management
|
|
|
|
```python
|
|
# Start a trial
|
|
result = ironlicensing.start_trial("user@example.com")
|
|
|
|
if result.valid:
|
|
print("Trial started!")
|
|
print(f"Expires: {result.license.expires_at}")
|
|
|
|
# Check if trial
|
|
if ironlicensing.is_trial():
|
|
show_trial_banner(ironlicensing.get_license().expires_at)
|
|
```
|
|
|
|
## Purchase Flow
|
|
|
|
```python
|
|
# Get available tiers
|
|
tiers = ironlicensing.get_tiers()
|
|
|
|
for tier in tiers:
|
|
print(f"{tier.name}: {tier.price} {tier.currency}/{tier.billing_period}")
|
|
|
|
# Start checkout
|
|
checkout = ironlicensing.start_purchase("tier-pro", "user@example.com")
|
|
|
|
if checkout.success:
|
|
# Open checkout URL
|
|
print(f"Checkout URL: {checkout.checkout_url}")
|
|
```
|
|
|
|
## Deactivation
|
|
|
|
```python
|
|
# Deactivate on this machine
|
|
if ironlicensing.deactivate():
|
|
print("License deactivated")
|
|
```
|
|
|
|
## License Change Events
|
|
|
|
```python
|
|
def on_license_change(license):
|
|
if license:
|
|
print(f"License updated: {license.status}")
|
|
else:
|
|
print("License removed")
|
|
|
|
# Listen for license changes
|
|
unsubscribe = client.on_license_change(on_license_change)
|
|
|
|
# Later: unsubscribe
|
|
unsubscribe()
|
|
```
|
|
|
|
## Offline Support
|
|
|
|
The SDK automatically caches validation results and supports offline usage:
|
|
|
|
```python
|
|
client = LicenseClient(LicenseOptions(
|
|
public_key="pk_live_xxxxx",
|
|
product_slug="my-app",
|
|
enable_offline_cache=True,
|
|
cache_validation_minutes=60, # Use cache for 60 minutes
|
|
offline_grace_days=7, # Allow 7 days offline
|
|
))
|
|
|
|
# This will use cache if available
|
|
result = client.validate()
|
|
|
|
if result.cached:
|
|
print("Using cached validation")
|
|
```
|
|
|
|
## Requirements
|
|
|
|
- Python 3.8+
|
|
- httpx
|
|
|
|
## License
|
|
|
|
MIT License - see [LICENSE](LICENSE) for details.
|