CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyarmor

A command-line tool for obfuscating Python scripts, binding obfuscated scripts to specific machines, and setting expiration dates

Pending
Overview
Eval results
Files

licensing.mddocs/

License Management

PyArmor provides comprehensive license management for controlling access to obfuscated scripts through hardware binding, time-based restrictions, and custom user data. The licensing system enables software vendors to protect their applications and control distribution with flexible restriction mechanisms.

Capabilities

License Generation

License Key Creation

Generate license files with custom restrictions and hardware binding for obfuscated scripts.

def make_license_key(capsule, code: str, filename: str, **kwargs) -> None:
    """
    Generate license key file with specified restrictions.
    
    Args:
        capsule: Protection capsule path or object
        code (str): License registration code
        filename (str): Output license file path
        **kwargs: License options
            - expired (str): Expiration date in YYYY-MM-DD format
            - bind_disk (str): Bind to hard disk serial number
            - bind_mac (str): Bind to MAC address
            - bind_ipv4 (str): Bind to IPv4 address
            - bind_domain (str): Bind to domain name
            - bind_file (str): Bind to specific file checksum
            - enable_period_mode (bool): Enable periodic validation
            - period (int): Validation period in days
            - data (str): Custom user data to embed
    
    Raises:
        LicenseError: If license generation fails
        ValueError: If code format is invalid
        BindingError: If hardware binding fails
    """

def generate_group_license(code: str, count: int, **kwargs) -> list:
    """
    Generate multiple license files for group licensing.
    
    Args:
        code (str): Base license code
        count (int): Number of licenses to generate
        **kwargs: Group license options
            - prefix (str): License file name prefix
            - output (str): Output directory
            - bind_template (str): Hardware binding template
    
    Returns:
        list: List of generated license file paths
    """

def make_trial_license(capsule, days: int, **kwargs) -> str:
    """
    Generate time-limited trial license.
    
    Args:
        capsule: Protection capsule
        days (int): Trial period in days
        **kwargs: Trial options
            - features (list): Enabled features for trial
            - bind_data (str): Custom trial data
    
    Returns:
        str: Path to generated trial license
    """

Registration Management

Registration Functions

Handle PyArmor registration codes and license activation for commercial usage.

def get_registration_code() -> str:
    """
    Get current PyArmor registration code.
    
    Returns:
        str: Current registration code or empty string if unregistered
    """

def query_keyinfo(key: str) -> dict:
    """
    Query registration key information from server.
    
    Args:
        key (str): Registration key to query
        
    Returns:
        dict: Key information including features, expiration, device limits
            - product (str): Product name
            - version (str): License version
            - lictype (str): License type (TRIAL, BASIC, PRO, etc.)
            - features (list): Enabled features
            - expired (str): Expiration date
            - devices (int): Maximum device count
            - platform (str): Platform restrictions
    
    Raises:
        NetworkError: If unable to connect to server
        KeyError: If key is invalid or not found
    """

def activate_regcode(ucode: str) -> dict:
    """
    Activate PyArmor registration code.
    
    Args:
        ucode (str): Registration code from purchase
        
    Returns:
        dict: Activation result with license information
    
    Raises:
        ActivationError: If activation fails
        NetworkError: If server communication fails
    """

def register_keyfile(keyfile: str, upgrade: bool = None, legency: bool = False) -> None:
    """
    Register PyArmor using license keyfile.
    
    Args:
        keyfile (str): Path to license keyfile (.zip or .txt)
        upgrade (bool, optional): Upgrade existing license
        legency (bool): Handle legacy license format
    
    Raises:
        RegistrationError: If registration fails
        FileNotFoundError: If keyfile doesn't exist
        FormatError: If keyfile format is invalid
    """

def upgrade_license(filename: str) -> dict:
    """
    Upgrade existing license to newer version.
    
    Args:
        filename (str): License file to upgrade
        
    Returns:
        dict: Upgrade result information
    """

Modern Registration System (v8+)

Enhanced registration management with web integration and group licensing.

class Register:
    """
    Modern license registration management.
    """
    
    def __init__(self, ctx):
        """
        Initialize register with context.
        
        Args:
            ctx (Context): PyArmor context instance
        """
    
    def register_regfile(self, regfile: str) -> None:
        """
        Register using registration file.
        
        Args:
            regfile (str): Registration file path
        """
    
    def generate_group_device(self, device_id: int) -> None:
        """
        Generate device file for group licensing.
        
        Args:
            device_id (int): Device ID (1-100)
        """
    
    def check_group_license(self) -> dict:
        """
        Check group license status and device allocation.
        
        Returns:
            dict: Group license information
        """

class WebRegister:
    """
    Web-based registration with online validation.
    """
    
    def check_request_interval(self) -> None:
        """
        Check if sufficient time has passed since last request.
        
        Raises:
            RateLimitError: If too many requests made recently
        """
    
    def register_group_device(self, regfile: str, device: int) -> None:
        """
        Register device in group license online.
        
        Args:
            regfile (str): Group registration file
            device (int): Device ID to register
        """
    
    def request_ci_regfile(self, regfile: str) -> None:
        """
        Request CI/CD pipeline registration file.
        
        Args:
            regfile (str): Base registration file
        """
    
    def prepare(self, regfile: str, product: str, upgrade: bool = False) -> tuple:
        """
        Prepare registration with validation.
        
        Args:
            regfile (str): Registration file path
            product (str): Product name
            upgrade (bool): Upgrade existing registration
            
        Returns:
            tuple: (registration_info, confirmation_message)
        """
    
    def register(self, regfile: str, product: str, group: bool = False) -> None:
        """
        Complete registration process.
        
        Args:
            regfile (str): Registration file
            product (str): Product name  
            group (bool): Group license registration
        """
    
    def upgrade_to_pro(self, regfile: str, product: str) -> None:
        """
        Upgrade license to professional version.
        
        Args:
            regfile (str): Registration file
            product (str): Product name
        """

Hardware Binding

Device Information Functions

def show_hd_info(name: str = None) -> str:
    """
    Display hardware information for binding configuration.
    
    Args:
        name (str, optional): Specific hardware component name
            - 'disk': Hard disk serial numbers
            - 'mac': MAC addresses  
            - 'ipv4': IPv4 addresses
            - 'domain': Domain name
            - 'cpu': CPU information
    
    Returns:
        str: Formatted hardware information
    
    Example output:
        Hardware information:
        Disk serial number: ABCD1234567890
        MAC address: 00:11:22:33:44:55
        IPv4 address: 192.168.1.100
        Domain name: example.com
    """

def get_bind_key(hdtype: str, name: str = None) -> str:
    """
    Get hardware binding key for specific device.
    
    Args:
        hdtype (str): Hardware type ('disk', 'mac', 'ipv4', 'domain')
        name (str, optional): Specific device name
        
    Returns:
        str: Hardware binding key
    """

def validate_bind_key(key: str, hdtype: str) -> bool:
    """
    Validate hardware binding key against current system.
    
    Args:
        key (str): Hardware binding key to validate
        hdtype (str): Expected hardware type
        
    Returns:
        bool: True if key matches current hardware
    """

License Validation

Runtime License Checking

def check_license(license_file: str) -> dict:
    """
    Validate license file and return restrictions.
    
    Args:
        license_file (str): Path to license file
        
    Returns:
        dict: License validation result
            - valid (bool): License validity
            - expired (str): Expiration date
            - devices (list): Bound device information
            - features (list): Enabled features
            - data (str): Custom user data
    
    Raises:
        LicenseError: If license is invalid or corrupted
        ExpiredError: If license has expired
        BindingError: If hardware binding fails
    """

def enable_period_mode(license_file: str, period: int) -> None:
    """
    Enable periodic license validation.
    
    Args:
        license_file (str): License file to modify
        period (int): Validation period in days
    """

def validate_periodic_license() -> bool:
    """
    Perform periodic license validation check.
    
    Returns:
        bool: True if validation passes
        
    Raises:
        ValidationError: If periodic validation fails
        NetworkError: If unable to contact validation server
    """

Usage Examples

Basic License Generation

from pyarmor import utils

# Generate capsule
capsule = utils.make_capsule()

# Create basic license
utils.make_license_key(
    capsule,
    "MYAPP-USER001",
    "licenses/user001.lic"
)

# Create time-limited license
utils.make_license_key(
    capsule,
    "MYAPP-TRIAL",
    "licenses/trial.lic",
    expired="2024-12-31"
)

Hardware Binding

# Show available hardware information
print(utils.show_hd_info())

# Create MAC-bound license
utils.make_license_key(
    capsule,
    "MYAPP-MACHINE001", 
    "licenses/machine001.lic",
    bind_mac="00:11:22:33:44:55"
)

# Create disk-bound license with expiration
utils.make_license_key(
    capsule,
    "MYAPP-WORKSTATION",
    "licenses/workstation.lic", 
    bind_disk="ABCD1234567890",
    expired="2025-06-30"
)

# Multiple binding constraints
utils.make_license_key(
    capsule,
    "MYAPP-SECURE",
    "licenses/secure.lic",
    bind_mac="00:11:22:33:44:55",
    bind_ipv4="192.168.1.100",
    bind_domain="company.com",
    expired="2024-12-31"
)

Group Licensing

from pyarmor.register import generate_group_license

# Generate 10 licenses for group deployment
licenses = generate_group_license(
    "MYAPP-GROUP001",
    10,
    prefix="dept_license_",
    output="licenses/group/",
    expired="2025-12-31"
)

for lic_path in licenses:
    print(f"Generated: {lic_path}")

Periodic Validation

# Create license with periodic checking
utils.make_license_key(
    capsule,
    "MYAPP-SUBSCRIPTION",
    "licenses/subscription.lic",
    enable_period_mode=True,
    period=30,  # Check every 30 days
    expired="2025-12-31"
)

# Enable periodic mode on existing license
utils.enable_period_mode("licenses/subscription.lic", 7)  # Weekly checks

Registration Management

from pyarmor import register

# Check current registration
reg_code = register.get_registration_code()
if reg_code:
    print(f"Registered with: {reg_code}")
else:
    print("PyArmor is not registered")

# Query key information
try:
    key_info = register.query_keyinfo("PYARMOR-KEY-XXXX")
    print(f"Product: {key_info['product']}")
    print(f"License Type: {key_info['lictype']}")
    print(f"Features: {key_info['features']}")
    print(f"Expires: {key_info['expired']}")
except Exception as e:
    print(f"Key query failed: {e}")

# Register PyArmor
register.register_keyfile("pyarmor-regfile-xxxx.zip")

Modern Registration (v8+)

from pyarmor.cli.register import Register, WebRegister
from pyarmor.cli.context import Context

ctx = Context()

# Local registration
reg = Register(ctx)
reg.register_regfile("pyarmor-regfile-xxxx.zip")

# Web registration
web_reg = WebRegister(ctx)
web_reg.check_request_interval()  # Rate limiting

# Register with product binding
info, msg = web_reg.prepare("pyarmor-regcode-xxxx.txt", "MyProduct")
print(msg)
web_reg.register("pyarmor-regcode-xxxx.txt", "MyProduct")

License Validation in Applications

from pyarmor.utils import check_license

try:
    # Validate license at application startup
    license_info = check_license("app.lic")
    
    if license_info['valid']:
        print("License valid")
        print(f"Expires: {license_info['expired']}")
        
        # Check custom data
        if 'data' in license_info:
            print(f"User data: {license_info['data']}")
            
    else:
        print("Invalid license")
        exit(1)
        
except Exception as e:
    print(f"License validation failed: {e}")
    exit(1)

# Periodic validation
if not validate_periodic_license():
    print("Periodic validation failed")
    exit(1)

Error Handling

from pyarmor.utils import LicenseError, BindingError, ExpiredError
from pyarmor.register import RegistrationError, NetworkError

try:
    # License operations
    utils.make_license_key(capsule, "CODE", "license.lic", 
                          bind_mac="invalid-mac")
    
except LicenseError as e:
    print(f"License generation failed: {e}")
    
except BindingError as e:
    print(f"Hardware binding failed: {e}")
    
try:
    # Registration operations
    register.register_keyfile("keyfile.zip")
    
except RegistrationError as e:
    print(f"Registration failed: {e}")
    
except NetworkError as e:
    print(f"Network error during registration: {e}")
    
try:
    # License validation
    license_info = check_license("app.lic")
    
except ExpiredError as e:
    print(f"License expired: {e}")
    
except BindingError as e:
    print(f"Hardware binding mismatch: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-pyarmor

docs

cli.md

configuration.md

index.md

licensing.md

obfuscation.md

platform-support.md

project-management.md

tile.json