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

configuration.mddocs/

Configuration Management

PyArmor provides hierarchical configuration management with global, local, and project-specific settings. The configuration system supports interactive shell editing, programmatic access, and persistent storage of obfuscation parameters and environment settings.

Capabilities

Configuration Manager (v8+)

Modern configuration management with hierarchical settings and validation.

class Configer:
    """
    Configuration file management and validation.
    """
    
    def __init__(self, ctx, encoding: str = None):
        """
        Initialize configuration manager.
        
        Args:
            ctx (Context): PyArmor context instance
            encoding (str, optional): Configuration file encoding
        """
    
    def list_sections(self, local: bool = True, name: str = None) -> list:
        """
        List available configuration sections.
        
        Args:
            local (bool): Include local settings (default: True)
            name (str, optional): Filter by section name pattern
            
        Returns:
            list: Available configuration sections
            
        Example sections:
            ['pyarmor', 'builder', 'runtime', 'finder', 'mix', 'assert']
        """
    
    def list_options(self, sect: str, local: bool = True, name: str = None) -> list:
        """
        List options in a configuration section.
        
        Args:
            sect (str): Section name
            local (bool): Include local settings
            name (str, optional): Filter by option name pattern
            
        Returns:
            list: Available options in section
        """
    
    def run(self, options: list, local: bool, name: str) -> None:
        """
        Execute configuration commands.
        
        Args:
            options (list): Configuration options to set/query
            local (bool): Apply to local settings
            name (str): Private settings name for module/package
            
        Options format:
            ['option'] - Query option value
            ['option=value'] - Set option value
            ['section.option=value'] - Set section-specific option
        """
    
    def reset(self, options: list, local: bool, name: str) -> None:
        """
        Reset configuration options to defaults.
        
        Args:
            options (list): Options to reset
            local (bool): Reset local settings
            name (str): Private settings name
        """

Context Management

Central context and environment management for PyArmor operations.

class Context:
    """
    PyArmor execution context and environment management.
    """
    
    def __init__(self, *paths):
        """
        Initialize context with optional home path configuration.
        
        Args:
            *paths: Home directory paths (home, data, temp, config)
        """
    
    def push(self, options: dict) -> None:
        """
        Push configuration options to context stack.
        
        Args:
            options (dict): Configuration options to apply
        """
    
    def pop(self) -> dict:
        """
        Pop configuration options from context stack.
        
        Returns:
            dict: Popped configuration options
        """
    
    def get_res_options(self, fullname: str, catalog: str) -> dict:
        """
        Get resource-specific configuration options.
        
        Args:
            fullname (str): Full resource name (module.submodule)
            catalog (str): Resource catalog type
            
        Returns:
            dict: Resource-specific configuration
        """
    
    def version_info(self) -> str:
        """
        Get PyArmor version information.
        
        Returns:
            str: Formatted version string
        """
        
    # Context Properties
    @property
    def pyarmor_platform(self) -> str:
        """Current PyArmor platform specification."""
        
    @property  
    def native_platform(self) -> str:
        """Native system platform specification."""
        
    @property
    def home_path(self) -> str:
        """PyArmor home directory path."""
        
    @property
    def runtime_platforms(self) -> list:
        """List of configured runtime platforms."""
        
    @property
    def runtime_outer(self) -> bool:
        """Whether outer runtime key is enabled."""
        
    @property
    def runtime_key(self) -> bytes:
        """Current runtime key data."""
        
    @property
    def runtime_keyfile(self) -> str:
        """Runtime key file name."""

Interactive Configuration Shell

class PyarmorShell:
    """
    Interactive command-line shell for configuration management.
    """
    
    def __init__(self, ctx):
        """
        Initialize interactive shell.
        
        Args:
            ctx (Context): PyArmor context instance
        """
    
    def cmdloop(self, intro: str = None) -> None:
        """
        Start interactive command loop.
        
        Args:
            intro (str, optional): Introduction message
        """
    
    def do_cfg(self, line: str) -> None:
        """
        Configuration command handler.
        
        Args:
            line (str): Command line arguments
        """
    
    def do_show(self, line: str) -> None:
        """
        Show configuration values.
        
        Args:
            line (str): Configuration keys to display
        """
    
    def do_set(self, line: str) -> None:
        """
        Set configuration values.
        
        Args:
            line (str): Configuration assignments
        """
    
    def do_reset(self, line: str) -> None:
        """
        Reset configuration to defaults.
        
        Args:
            line (str): Configuration keys to reset
        """

Configuration Hierarchy

Configuration Domains

# Configuration precedence (highest to lowest):
CONFIG_DOMAINS = {
    'command_line': 'Command line arguments',
    'project': 'Project-specific settings',
    'local': 'Local directory settings (.pyarmor_config)',
    'global': 'Global user settings (~/.pyarmor/config.ini)',
    'default': 'Built-in default values'
}

# Configuration file locations
CONFIG_PATHS = {
    'global': '~/.pyarmor/config.ini',
    'local': './.pyarmor_config', 
    'project': './pyarmor.json'
}

Core Configuration Sections

class PyarmorConfig:
    """Core PyArmor configuration options."""
    
    # Version and licensing
    version: str           # PyArmor version
    cli_runtime: str       # CLI runtime version
    buyurl: str           # Purchase URL
    
class BuilderConfig:
    """Obfuscation builder configuration."""
    
    # Obfuscation settings
    obf_module: int           # Module obfuscation (0/1)
    obf_code: int            # Code obfuscation (0/1/2)
    wrap_mode: int           # Wrap mode (0/1)
    mix_str: int             # String mixing (0/1)
    
    # Advanced settings
    enable_bcc: int          # BCC mode (0/1)
    enable_jit: int          # JIT mode (0/1)
    enable_rft: int          # RFT mode (0/1)
    enable_themida: int      # Themida protection (0/1)
    
    # Restriction settings
    restrict_module: int     # Module restriction (0-3)
    assert_call: int         # Function call assertion (0/1)
    assert_import: int       # Import assertion (0/1)
    
    # Platform settings
    runtime_platforms: str   # Target platforms
    enable_trace: int        # Trace mode (0/1)
    
class RuntimeConfig:
    """Runtime package configuration."""
    
    # Runtime settings
    outer: int              # Outer runtime key (0/1)
    period: int             # Validation period (days)
    expired: str            # Expiration date
    devices: str            # Bound devices
    
    # Package settings
    import_prefix: str      # Import prefix
    package_runtime: int    # Package with scripts (0/1)
    
class FinderConfig:
    """Resource finder configuration."""
    
    # Discovery settings
    recursive: int          # Recursive search (0/1)
    findall: int           # Find all files (0/1)
    
    # Filter settings
    includes: str          # Include patterns
    excludes: str          # Exclude patterns

Configuration File Formats

Global Configuration (INI format)

[pyarmor]
version = 9.1.8
cli.runtime = 7.6.7
buyurl = https://jondy.github.io/paypal/index.html

[builder]
obf_module = 1
obf_code = 1
wrap_mode = 1
mix_str = 0
enable_bcc = 0
enable_jit = 0
enable_rft = 0
enable_themida = 0
restrict_module = 0
assert_call = 0
assert_import = 0
enable_trace = 0

[runtime]
outer = 0
import_prefix = 
package_runtime = 0

[finder]
recursive = 1
findall = 0
includes = 
excludes = __pycache__, *.pyc, test_*, *test.py

Project Configuration (JSON format)

{
  "name": "MyProject",
  "version": "1.0.0",
  "src": "src",
  "output": "dist", 
  "entry": "main.py",
  "obf_code": 2,
  "obf_mod": 1,
  "wrap_mode": 1,
  "advanced_mode": 2,
  "restrict_mode": 2,
  "mix_str": 1,
  "platforms": ["linux.x86_64", "windows.x86_64"],
  "runtime_path": "runtime",
  "package_runtime": 1,
  "license_file": "app.lic"
}

Usage Examples

Basic Configuration Management

from pyarmor.cli.config import Configer
from pyarmor.cli.context import Context

# Initialize configuration
ctx = Context()
cfg = Configer(ctx)

# List all sections
sections = cfg.list_sections()
print("Available sections:", sections)

# List options in builder section
options = cfg.list_options('builder')
print("Builder options:", options)

# Show current configuration
cfg.run(['builder.obf_code'], local=True, name=None)

# Set configuration values
cfg.run(['builder.obf_code=2'], local=True, name=None)
cfg.run(['builder.mix_str=1'], local=True, name=None)

# Reset to defaults
cfg.reset(['builder.obf_code'], local=True, name=None)

Context Management

from pyarmor.cli.context import Context

# Initialize context
ctx = Context()

# Check platform information
print(f"PyArmor platform: {ctx.pyarmor_platform}")
print(f"Native platform: {ctx.native_platform}")
print(f"Home path: {ctx.home_path}")

# Push configuration options
options = {
    'obf_code': 2,
    'mix_str': True,
    'restrict_module': 2,
    'platforms': ['linux.x86_64', 'windows.x86_64']
}
ctx.push(options)

# Get resource-specific options
res_options = ctx.get_res_options('mypackage.module', 'Python')
print("Resource options:", res_options)

# Pop configuration
old_options = ctx.pop()

Interactive Shell Usage

from pyarmor.cli.shell import PyarmorShell
from pyarmor.cli.context import Context

# Start interactive shell
ctx = Context()
shell = PyarmorShell(ctx)

# Example shell session:
# (pyarmor) cfg builder.obf_code
# builder.obf_code = 1
# 
# (pyarmor) set builder.obf_code=2
# Set builder.obf_code = 2
#
# (pyarmor) show builder
# [builder]
# obf_code = 2
# obf_module = 1
# wrap_mode = 1
#
# (pyarmor) reset builder.obf_code
# Reset builder.obf_code to default value

shell.cmdloop("PyArmor Configuration Shell")

Hierarchical Configuration

# Global configuration (affects all projects)
cfg.run(['builder.obf_code=1'], local=False, name=None)

# Local configuration (current directory)
cfg.run(['builder.obf_code=2'], local=True, name=None)

# Private configuration (specific module)
cfg.run(['builder.mix_str=1'], local=True, name='sensitive_module')

# Project-specific configuration
# (handled by project management system)

Environment Setup

from pyarmor.cli.context import Context
import os

# Configure PyArmor home directory
os.environ['PYARMOR_HOME'] = '/custom/pyarmor/home'

# Initialize with custom paths
ctx = Context('/custom/home', '/custom/data', '/custom/temp', '/custom/config')

# Check environment
print(f"Version: {ctx.version_info()}")
print(f"Platform: {ctx.pyarmor_platform}")
print(f"Runtime platforms: {ctx.runtime_platforms}")

# Validate environment setup
if ctx.runtime_platforms:
    print("Runtime platforms configured")
else:
    print("No runtime platforms configured")

Advanced Configuration Patterns

# Configure cross-platform obfuscation
cfg.run([
    'builder.runtime_platforms=linux.x86_64 windows.x86_64 darwin.x86_64'
], local=True, name=None)

# Configure maximum protection
cfg.run([
    'builder.obf_code=2',
    'builder.mix_str=1', 
    'builder.enable_bcc=1',
    'builder.restrict_module=3',
    'builder.assert_call=1',
    'builder.assert_import=1'
], local=True, name=None)

# Configure development settings
cfg.run([
    'builder.obf_code=1',
    'builder.enable_trace=1',
    'finder.excludes=test_*, __pycache__, *.pyc'
], local=True, name=None)

# Module-specific configuration
cfg.run([
    'builder.obf_code=2',
    'builder.mix_str=1'
], local=True, name='critical_module')

cfg.run([
    'builder.obf_code=0'  # No obfuscation for debug module
], local=True, name='debug_module')

Configuration Validation

# Validate configuration consistency
def validate_config(cfg):
    """Validate PyArmor configuration for common issues."""
    
    issues = []
    
    # Check BCC mode compatibility
    bcc_enabled = cfg.list_options('builder').get('enable_bcc', 0)
    platforms = cfg.list_options('builder').get('runtime_platforms', '')
    
    if bcc_enabled and len(platforms.split()) > 1:
        issues.append("BCC mode does not support cross-platform obfuscation")
    
    # Check Themida compatibility
    themida_enabled = cfg.list_options('builder').get('enable_themida', 0)
    if themida_enabled and not any(p.startswith('windows') for p in platforms.split()):
        issues.append("Themida protection requires Windows platform")
    
    # Check restriction mode compatibility
    restrict_mode = cfg.list_options('builder').get('restrict_module', 0)
    outer_key = cfg.list_options('runtime').get('outer', 0)
    
    if restrict_mode >= 2 and not outer_key:
        issues.append("Private/Restrict mode recommended with outer runtime key")
    
    return issues

# Validate current configuration
issues = validate_config(cfg)
if issues:
    print("Configuration issues found:")
    for issue in issues:
        print(f"  - {issue}")

Error Handling

from pyarmor.cli import CliError
from configparser import ConfigParser

try:
    # Configuration operations
    cfg.run(['invalid.option=value'], local=True, name=None)
    
except CliError as e:
    print(f"Configuration error: {e}")
    
except FileNotFoundError:
    print("Configuration file not found")
    
except PermissionError:
    print("Permission denied accessing configuration")

# Safe configuration access
def get_config_option(cfg, section, option, default=None):
    """Safely get configuration option with default fallback."""
    try:
        options = cfg.list_options(section)
        return options.get(option, default)
    except Exception:
        return default

# Example usage
obf_code = get_config_option(cfg, 'builder', 'obf_code', 1)
mix_str = get_config_option(cfg, 'builder', 'mix_str', 0)

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