Skip to main content

Framework-agnostic Python SDK for DevPayr โ€“ License enforcement, injectables, project & license management

Project description

๐Ÿ“˜ Introduction

DevPayr Python SDK is the official framework-agnostic client for integrating with DevPayr โ€” a modern licensing, domain enforcement, and injectable delivery system for SaaS and software products.

This SDK enables Python developers to:

  • โœ… Validate license keys securely (with or without payment enforcement)
  • ๐Ÿ” Stream and decrypt encrypted injectables from the DevPayr backend
  • ๐ŸŒ Enforce domain/subdomain access using DevPayr's project-bound policies
  • โš™๏ธ Manage projects, licenses, domains, API keys, and more
  • ๐Ÿ” Handle automatic revalidation or failover behavior for expired or revoked licenses

It is designed to work with any Python environment, including:

  • ๐Ÿ Flask, Django, FastAPI, or any other Python web framework
  • ๐Ÿงฉ CLI scripts, background jobs, or system-level services
  • ๐ŸŽฏ Desktop software or headless backend processors

You remain fully in control of what happens when a license is invalid โ€” show a modal, redirect users, log silently, or define a custom error handler.

Get started in minutes and enforce your license policies with confidence.

๐Ÿ“ฆ Installation

You can install the DevPayr Python SDK using either pip or by cloning the repository.

โœ… Option 1: Install via pip (recommended)

If you're using PyPi (when published):

pip install devpayr-python-sdk

๐Ÿ”ง Option 2: Install via source (for local development)

  1. Clone the repository:
git clone https://github.com/xultech/devpayr-python-sdk.git
cd devpayr-python-sdk
  1. Install in editable mode:
pip install -e .

This allows you to edit the SDK source locally and test changes instantly without reinstalling.

๐Ÿ“ Optional Dependencies

If you want to enable encryption or validation features, the SDK automatically includes:

  • requests
  • cryptography

To install these manually (if needed):

pip install requests cryptography

You're now ready to initialize DevPayr.bootstrap() and begin validating license keys or streaming injectables.

๐Ÿš€ Getting Started

This section walks you through how to quickly set up and use the DevPayr SDK in your Python application.

๐Ÿ” Basic Usage

from devpayr import DevPayr

DevPayr.bootstrap({
    "license": "your-test-license-key",   # Required if using license mode
    "api_key": "your-api-key",            # Optional if using API key mode
    "base_url": "https://api.devpayr.dev/api/v1/",  # Or your custom/self-hosted URL
    "secret": "your-shared-secret",       # For decrypting injectables
    "injectables": True,
    "handleInjectables": True,
    "injectablesVerify": True,
    "injectablesPath": "./dev_injectables",
    "invalidBehavior": "modal",           # Can be: modal, redirect, log, silent
    "redirectUrl": "https://yourdomain.com/upgrade",
    "customInvalidMessage": "License check failed. Please contact support.",
    "onReady": lambda data: print("โœ… Validated:", data)
})

โš ๏ธ Note: If using injectables, you must specify secret and injectablesPath. In fact, secret is always required

๐Ÿงช Validate License Before Execution

When using license validation (license key), the SDK will automatically:

  • Contact DevPayrโ€™s API
  • Validate payment or subscription
  • Optionally fetch and decrypt injectables
  • Trigger a failure behavior (modal, redirect, log, or silent)

๐Ÿ›  Behavior on Invalid License

You can control what happens when the license is invalid via:

Mode Description
modal Displays a styled HTML page to block app usage (default)
redirect Opens a browser tab to a custom upgrade/payment URL
log Prints an error message to stderr
silent Does nothing (silent failure โ€” use with caution)

๐Ÿ“ Injectables Handling

If injectables = True, the SDK will:

  • Stream encrypted files for that license
  • Decrypt and verify using secret
  • Write them to injectablesPath
  • Support modes like append, prepend, replace

You can also override the default handler via a custom InjectableProcessor.


Now that you're set up, you can start accessing DevPayr's API through built-in service classes like:

from devpayr import DevPayr

DevPayr.projects().create({...})
DevPayr.licenses().list(project_id)
DevPayr.injectables().stream()

โš™๏ธ Usage Examples

Here are some common examples of how to use the DevPayr Python SDK:


โœ… Basic License Validation

from devpayr import DevPayr

DevPayr.bootstrap({
    "license": "your-license-key",
    "secret": "your-shared-secret",
    "injectables": True,
    "onReady": lambda data: print("โœ… License valid:", data),
    "invalidBehavior": "modal",  # Options: modal, redirect, log, silent
})

Alternatively, if you want more control:

from devpayr import Config, RuntimeValidator

config = Config({
    "license": "your-license-key",
    "secret": "your-shared-secret",
    "injectables": True
})

validator = RuntimeValidator(config)
result = validator.validate()
print("โœ… License valid:", result)

๐Ÿš€ Project Creation

from devpayr import DevPayr

DevPayr.bootstrap({ "api_key": "your-api-key" })

project = DevPayr.projects().create({
    "name": "My App",
    "description": "A sample project",
    "is_active": True
})

print("๐Ÿ“ Project created:", project)

Or manually:

from devpayr import Config, ProjectService

config = Config({ "api_key": "your-api-key" })
project_service = ProjectService(config)

project = project_service.create({
    "name": "My App",
    "description": "A sample project",
    "is_active": True
})

print("๐Ÿ“ Project created:", project)

๐Ÿ”‘ License Management

from devpayr import DevPayr

DevPayr.bootstrap({ "api_key": "your-api-key" })

licenses = DevPayr.licenses().list(project_id=1)
print("๐Ÿ” Licenses:", licenses)

Or:

from devpayr import Config, LicenseService

config = Config({ "api_key": "your-api-key" })
license_service = LicenseService(config)

licenses = license_service.list(project_id=1)

๐ŸŒ Domain Management

from devpayr import DevPayr

DevPayr.bootstrap({ "api_key": "your-api-key" })

domain = DevPayr.domains().create(project_id=1, data={
    "domain": "example.com"
})

๐Ÿ“ฆ Injectable Streaming

from devpayr import DevPayr

DevPayr.bootstrap({
    "license": "your-license-key",
    "secret": "your-shared-secret",
    "injectables": True
})

# Injectables are automatically processed and written to file.

You can also fetch them manually:

from devpayr import Config, InjectableService

config = Config({
    "license": "your-license-key",
    "secret": "your-shared-secret"
})

service = InjectableService(config)
injectables = service.stream()
print("๐Ÿ“ฆ Injectables:", injectables)

๐Ÿ” Runtime Validation & Injectables

The DevPayr Python SDK supports runtime license validation and secure injectable management. When configured, the SDK automatically validates your license and handles injectables securely.

๐Ÿงช How It Works

  1. License Validation
    When DevPayr.bootstrap() is called with a license and secret, the SDK makes a call to the DevPayr backend to validate the license using your secret.

  2. Injectable Fetching
    If injectables=True, the SDK will request the encrypted injectables associated with your license.

  3. Decryption & Signature Verification
    Each injectable is:

    • Decrypted using AES-256-CBC with the secret
    • Verified using HMAC-SHA256 signature
  4. Writing Injectables
    If handleInjectables=True, verified injectables are written to your filesystem using the target_path and mode (append, prepend, replace).


๐Ÿ”’ Example Configuration

from devpayr import DevPayr

DevPayr.bootstrap({
    "license": "your-license-key",
    "secret": "your-shared-secret",
    "injectables": True,
    "handleInjectables": True,
    "injectablesVerify": True,
    "injectablesPath": "runtime/",
    "onReady": lambda data: print("โœ… All good:", data)
})

๐Ÿ’ก Notes

  • All written files are placed in injectablesPath (defaults to current directory).
  • Signature verification ensures content has not been tampered with.
  • You can set injectablesVerify=False to skip HMAC verification (not recommended).

๐Ÿงฐ Custom Injectable Processor

You can define your own custom injectable processor by implementing the InjectableProcessorInterface. This allows you to take full control of how injectables are decrypted, verified, and saved (e.g., storing in a DB, writing to disk, or injecting into memory).

To use a custom processor, simply pass it via the injectablesProcessor key in the DevPayr.bootstrap() config.

๐Ÿ”ง Example: Custom Processor Implementation

from devpayr.contracts.injectable_processor import InjectableProcessorInterface
from devpayr.crypto.crypto_helper import CryptoHelper
from devpayr.crypto.hash_helper import  HashHelper
import os

class MyInjectableProcessor(InjectableProcessorInterface):
    @staticmethod
    def handle(injectable: dict, secret: str, base_path: str, verify_signature: bool = True) -> str:
        encrypted = injectable.get("encrypted_content")
        signature = injectable.get("signature")

        if verify_signature:
            expected = HashHelper.signature(encrypted, secret)
            if signature != expected:
                raise Exception("Invalid injectable signature")

        decrypted = CryptoHelper.decrypt(encrypted, secret)
        target_path = os.path.join(base_path, injectable.get("target_path"))
        os.makedirs(os.path.dirname(target_path), exist_ok=True)

        with open(target_path, "w", encoding="utf-8") as f:
            f.write(decrypted)

        return target_path

โš™๏ธ Using the Processor

from devpayr import DevPayr

DevPayr.bootstrap({
    "license": "your-license-key",
    "secret": "your-shared-secret",
    "injectables": True,
    "handleInjectables": True,
    "injectablesProcessor": MyInjectableProcessor,
})

โœ… With this setup, your injectables will be processed using your custom logic instead of the default built-in handler.

โŒ Failure Modes & Behavior

When the SDK fails to validate a license (e.g., expired, revoked, or invalid), the invalidBehavior config key determines how the SDK should respond. This is useful for preventing unauthorized access while offering flexible handling strategies.


๐Ÿ› ๏ธ Supported invalidBehavior Options

Mode Description
modal Prints a styled HTML message to the screen (for CLI or frontend display). This is the default behavior.
redirect Opens the provided redirectUrl in the browser and exits. Useful in desktop or GUI apps.
log Logs the error message to stderr without exiting the program.
silent Suppresses all error output and continues execution (not recommended).

๐Ÿงพ Example

DevPayr.bootstrap({
    "license": "your-license-key",
    "secret": "your-shared-secret",
    "invalidBehavior": "redirect",
    "redirectUrl": "https://yourapp.com/license-error"
})

๐Ÿงฉ Custom Error Message or View

You can customize the modal output by using:

  • customInvalidMessage: A string to override the default error message.
  • customInvalidView: A path to your own .html file to render instead of the default modal.
DevPayr.bootstrap({
    "license": "your-license-key",
    "secret": "your-shared-secret",
    "invalidBehavior": "modal",
    "customInvalidMessage": "Your license is no longer valid. Please contact support.",
    "customInvalidView": "/path/to/custom_error.html"
})

๐Ÿ“Œ Note: If using modal, the SDK will attempt to render a default HTML view (resources/unlicensed.html) if no custom view is provided.

๐Ÿงช Testing

The DevPayr Python SDK includes direct test scripts within the tests/ directory for validating various components such as license validation, injectables handling, encryption, and service APIs.

These tests can be run individually without any test runner like pytest โ€” just using standard Python.


โœ… Running Tests

To run a test file, use:

python tests/test_runtime_validator.py

Or any other test file in the tests/ folder, for example:

python tests/test_crypto_and_hash.py
python tests/test_config.py

๐Ÿ™Œ Credits / Acknowledgments

The DevPayr Python SDK was developed by the team at XulTech as part of the broader DevPayr ecosystem.

๐Ÿ‘จโ€๐Ÿ’ป Lead Developer

๐Ÿ”ง Built With

  • requests โ€“ HTTP communication
  • cryptography โ€“ AES-256-CBC encryption
  • unittest.mock โ€“ Testing utilities

๐Ÿ’™ Inspired By

  • Common SDK patterns in the open-source community.
  • Feedback from real developers who wanted license protection without complexity.

Thank you for supporting DevPayr.
Together, weโ€™re building a safer world for developers and digital product creators.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devpayr_python_sdk-0.1.2.tar.gz (23.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

devpayr_python_sdk-0.1.2-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file devpayr_python_sdk-0.1.2.tar.gz.

File metadata

  • Download URL: devpayr_python_sdk-0.1.2.tar.gz
  • Upload date:
  • Size: 23.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.5

File hashes

Hashes for devpayr_python_sdk-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c82d05d763d902cffedffcf678ada67dc213da8156fcaf765af84d089fd24961
MD5 d86f477c2275ff265417cb694f10b28e
BLAKE2b-256 f263e160d81f530982038529bd4e174305eb4596eee4f2ce6fa4eb25c714ec35

See more details on using hashes here.

File details

Details for the file devpayr_python_sdk-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for devpayr_python_sdk-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f2a3101a23336145b8d055e71b6608c3c04071a8d17e074b0b0d5eba41f41d3c
MD5 fe4dcda45e8e0a39da4712952b813677
BLAKE2b-256 4a9818eb2f66234f4219d3b972b17ef24f3c96f2d6c87d6fd2e86b0903bf8e95

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page