ironlicensing-python/README.md

314 lines
7.8 KiB
Markdown

<p align="center">
<a href="https://ironlicensing.com">
<img src="https://ironlicensing.com/logo.png" alt="IronLicensing" width="120" />
</a>
</p>
<h1 align="center">IronLicensing SDK for Python</h1>
<p align="center">
<strong>Software licensing and activation for Python applications</strong>
</p>
<p align="center">
<a href="https://pypi.org/project/ironlicensing/"><img src="https://img.shields.io/pypi/v/ironlicensing.svg" alt="PyPI version"></a>
<a href="https://pypi.org/project/ironlicensing/"><img src="https://img.shields.io/pypi/pyversions/ironlicensing.svg" alt="Python versions"></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
</p>
<p align="center">
<a href="https://ironlicensing.com">Website</a>
<a href="https://ironlicensing.com/docs">Documentation</a>
<a href="https://ironlicensing.com/docs/python">Python Guide</a>
<a href="https://git.marketally.com/ironservices">Git</a>
</p>
---
**IronLicensing** helps you protect your software with flexible licensing, activations, and feature management. Built for developers who want simple, powerful licensing without the complexity.
## 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
## Documentation
For complete documentation, visit [ironlicensing.com/docs](https://ironlicensing.com/docs).
## Other SDKs
| Platform | Package |
|----------|---------|
| JavaScript/TypeScript | [@ironservices/licensing](https://git.marketally.com/ironservices/ironlicensing-js) |
| .NET | [IronLicensing.Client](https://git.marketally.com/ironservices/ironlicensing-dotnet) |
| Go | [ironlicensing-go](https://git.marketally.com/ironservices/ironlicensing-go) |
| Java | [ironlicensing-java](https://git.marketally.com/ironservices/ironlicensing-java) |
| Rust | [ironlicensing](https://git.marketally.com/ironservices/ironlicensing-rust) |
## Support
- **Documentation**: [ironlicensing.com/docs](https://ironlicensing.com/docs)
- **Email**: dev@ironservices.io
- **Issues**: [git.marketally.com/ironservices/ironlicensing-python/issues](https://git.marketally.com/ironservices/ironlicensing-python/issues)
## License
MIT License - see [LICENSE](LICENSE) for details.