Skip to content

Advanced Tutorial

This tutorial covers advanced PyLocket features: multi-platform protection, CI/CD automation, and the PyCharm plugin. It builds on the Basic Tutorial.


Multi-Platform Protection

PyLocket supports five platform targets:

Platform ID OS Architecture
win-x64 Windows x86_64
linux-x64 Linux x86_64
linux-arm64 Linux aarch64
macos-x64 macOS x86_64 (Intel)
macos-arm64 macOS Apple Silicon

Register Multiple Platforms

When creating an app, record the platform you primarily target:

pylocket apps create \
  --name "MyApp" \
  --platform win-x64

The --platform option takes a single value. The recorded platform target is informational; the operative platform is chosen per build when you run pylocket protect --platform, so one app can ship builds for every OS.

Protect Each Platform Separately

Each platform artifact must be protected individually:

# Windows
pylocket protect \
  --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 \
  --artifact dist/myapp.exe \
  --platform win-x64 \
  --python 3.12

# Linux (rename the extensionless PyInstaller onefile to .elf before upload)
mv dist/myapp dist/myapp.elf
pylocket protect \
  --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 \
  --artifact dist/myapp.elf \
  --platform linux-x64 \
  --python 3.12

# macOS (Apple Silicon)
pylocket protect \
  --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 \
  --artifact dist/myapp.app \
  --platform macos-arm64 \
  --python 3.12

Each platform produces its own Build ID. Track them independently:

pylocket status --build <windows-build-id>
pylocket status --build <linux-build-id>
pylocket status --build <macos-build-id>

Python Version Targeting

PyLocket protects bytecode at the specific Python version level. The protection engine detects the Python version from the artifact itself, so --python is optional. Pass it when you want to be explicit:

pylocket protect \
  --app 3f8a1c22-9b4e-4d17-a6f0-2c5e7d90b114 \
  --artifact dist/myapp.exe \
  --platform win-x64 \
  --python 3.12

Supported versions: 3.12, 3.13, 3.14

Note: --python is a hint used only when automatic detection fails. If you pass it, it should match the Python version used by your packaging tool (PyInstaller, cx_Freeze, etc.).


Automating Protection in CI/CD

PyLocket integrates into any CI/CD pipeline. Here is a GitHub Actions example:

# .github/workflows/protect.yml
name: Protect and Release

on:
  push:
    tags: ["v*"]

jobs:
  build-and-protect:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: |
          pip install pylocket pyinstaller
          pip install -r requirements.txt

      - name: Build executable
        run: |
          pyinstaller --onefile myapp.py
          # PyInstaller onefile on Linux is extensionless; rename it to .elf for upload
          mv dist/myapp dist/myapp.elf

      - name: Login to PyLocket
        env:
          PYLOCKET_TOKEN: ${{ secrets.PYLOCKET_TOKEN }}
        run: pylocket login --token "$PYLOCKET_TOKEN"

      - name: Protect artifact
        run: |
          pylocket protect \
            --app ${{ vars.PYLOCKET_APP_ID }} \
            --artifact dist/myapp.elf \
            --platform linux-x64 \
            --python 3.12 \
            --no-wait

      - name: Wait for protection
        run: |
          BUILD_ID=$(pylocket status --app ${{ vars.PYLOCKET_APP_ID }} --latest --format json | jq -r '.id')
          echo "BUILD_ID=$BUILD_ID" >> "$GITHUB_ENV"
          while true; do
            STATUS=$(pylocket status --build "$BUILD_ID" --format json | jq -r '.status')
            if [ "$STATUS" = "ready" ]; then break; fi
            if [ "$STATUS" = "failed" ] || [ "$STATUS" = "rejected" ]; then echo "Protection failed ($STATUS)"; exit 1; fi
            sleep 10
          done

      - name: Download protected output
        run: pylocket fetch --build "$BUILD_ID" --out dist/protected/

      - name: Upload release artifact
        uses: actions/upload-artifact@v4
        with:
          name: myapp-protected-linux-x64
          path: dist/protected/

The poll loop above is optional: pylocket protect waits by default, and adding --out dist/protected/ downloads the protected artifact in the same step. For detailed CI/CD setup, see CI/CD Integration.


Using the PyCharm Plugin

The PyLocket PyCharm plugin lets you protect applications directly from the IDE.

Installation

  1. Open PyCharm → SettingsPluginsMarketplace
  2. Search for "PyLocket"
  3. Click Install and restart PyCharm

Usage

  1. Open the PyLocket tool window (bottom panel)
  2. Click Login and enter your credentials
  3. The plugin auto-detects packaging configurations (PyInstaller spec files, setup.py, etc.)
  4. Select an artifact and click Protect
  5. Monitor the build status in the tool window
  6. Click Download when the build is ready

For detailed instructions, see PyCharm Plugin.


Using the Developer Portal

The Developer Portal provides a web interface for managing your PyLocket apps:

  • Dashboard: View all apps, recent builds, and license activity
  • Apps: Create and configure applications
  • Builds: View build history, status, and download protected artifacts
  • Licenses: Create, monitor, and revoke end-user licenses
  • Billing: View usage, invoices, and payment methods
  • Settings: Manage API keys, 2FA, and account preferences

Everything available in the portal is also available through the CLI and REST API.


API Keys for Automation

For programmatic access to the REST API, use API keys:

  1. Go to the Developer Portal → SettingsAPI Keys
  2. Click Generate API Key. If you already have one, the button reads Rotate Key instead — rotating replaces the old key, which stops working immediately.
  3. Copy the key straight away and store it securely (e.g. as a CI/CD secret). It is shown once and cannot be retrieved later; we only store a hash. If you lose it, generate a new one.

These keys are for the REST API. The CLI itself does not authenticate with them; it uses the session token issued by pylocket login.

For CI/CD, use an API key and call the REST API. Do not put your account password in a pipeline: it grants full account access, cannot be scoped or revoked without changing it everywhere, and non-interactive login stops working the moment you enable 2FA. And do not store a session token either, because it expires after 30 minutes.

An API key does not expire and can be revoked instantly by rotating it, which is why it is the right credential for automation. See CI/CD Integration for a ready-to-use protect script.

To create or rotate your API key without a browser:

pylocket auth api-keys rotate

Despite the name, this also creates your first key — there is no separate create command, and running it on an account with no key is valid. The key is printed once, so copy it immediately.

Warning: Rotating an API key invalidates the previous key immediately. Update all CI/CD pipelines and scripts before rotating.


Two-Factor Authentication

Enable 2FA for your developer account for additional security:

# Start setup (returns a QR code for your authenticator app)
pylocket auth 2fa setup

# Confirm with a code from your authenticator
pylocket auth 2fa confirm --code 123456

# Check 2FA status
pylocket auth 2fa status

# Disable 2FA (requires current code)
pylocket auth 2fa disable --code 123456

When 2FA is enabled, pylocket login will prompt for a TOTP code after your password.


Summary

In this tutorial you learned how to:

  • Protect applications for multiple platforms
  • Target specific Python versions
  • Automate protection in CI/CD pipelines
  • Use the PyCharm plugin and Developer Portal
  • Manage API keys and 2FA

Next Steps

Goal Guide
Publish for all three OSes end-to-end Multi-OS Publishing
Set up licensing and distribution Licensing Tutorial
Choose a distribution strategy Distribution Strategies
Format-specific protection guides How-To Guides
Full CLI reference CLI Reference