Python code protection
Project description
Industry-grade Python code protection.
For a comprehensive license management solution that is both developer- and user-friendly, check out the Stonefish License Manager.
Quickstart
Protecting Python Packages
To protect a Python project using the Stonefish Code Shield, ensure that it
includes a minimal
pyproject.toml
file. Then simple replace your build system (e.g., setuptools
) with
stonefish_code_shield
in the pyproject.toml
file:
[build-system]
# requires = ["setuptools"]
# build-backend = "setuptools.build_meta"
requires = ["stonefish-code-shield"]
build-backend = "stonefish_code_shield.build_meta"
# ...
# additional project metadata as per PEP 621
# <https://peps.python.org/pep-0621/>
# (recommended)
# ...
Done! Your project is now protected with Stonefish Code Shield. Try it out by running
pip install .
or
(pip install build)
python -m build . --wheel
Protecting Standalone Python Scripts
For individual Python files, you can use the scs
command-line utility:
scs /path/to/file.py
How Stonefish Protects Your Code
While compiled languages (C, C++, etc.) keep code hidden, Python packages ship their code to all users, who can access it in various ways. However, this changes when the code is built with the Stonefish Code Shield. Here are some examples of what happens:
Accessing Source Files
-
Without Stonefish Code Shield:
After installation, users will find the package code in, e.g.,
~/.local/lib/python3.12/site-packages/numpy
. (The path is different for different operation systems.) -
When building with the Stonefish Code Shield, though, a source code like
├── pyproject.toml └── stonefish_example └── __init__.py
is installed as
├── _agg │ ├── __init__.dat │ ├── __init__.py │ └── __pycache__ │ └── __init__.cpython-311.pyc ├── __init__.py └── __pycache__ └── __init__.cpython-311.pyc
All program logic is encrypted within the binary
__init__.dat
, while the actual source code remains protected.
inspect
— Inspect live objects
import stonefish_example
import inspect
print(inspect.getsource(stonefish_example.solve))
Without Stonefish | With Stonefish |
|
|
Dill
import stonefish_example
from dill.source import getsource
print(getsource(stonefish_example.solve))
Without Stonefish | With Stonefish |
|
|
IPython's ??
In [1]: import stonefish_example
In [2]: stonefish_example.solve??
Without Stonefish | With Stonefish |
|
|
dis — Disassembler for Python bytecode
import stonefish_example
import dis
dis.dis(stonefish_example.solve)
Without Stonefish | With Stonefish |
|
|
xdis
import stonefish_example
import xdis.std as dis
dis.dis(stonefish_example.solve)
Without Stonefish | With Stonefish |
|
|
decompyle3, uncompyle6 etc.
Those tools are meant to recreated Python code from .pyc
files.
Since Stonefish moves the actual code into an encrypted
decompyle3 ~/path/to/__init__.cpython-38.pyc
Without Stonefish | With Stonefish |
|
|
Guidelines
Here are some guidelines to keep in mind while working with Stonefish Code Shield:
-
Stonefish renames class and function names, so relying on the
__name__
attribute in your code won't be possible. -
Stonefish cannot yet handle relative
*
imports, e.g.,from .utils import *
Make all imports explicit:
from .utils import div_to_mod, Extractor
-
Stonefish discards private (underscored) names from the API. If you want your users to use these variables or functions, you'll have to rename them.
-
Users must add
*.dat
files to their package data, e.g.,[tool.setuptools.package-data] "*" = ["*.dat"]
in
pyproject.toml
. This is because the encrypted code must be shipped with the package. -
Local imports should be relative (
from . import x
) instead of using absolute imports (import x
) ifx/
orx.py
is an internal folder or directory. -
Stonefish places all data files in a flat directory structure, so it cannot handle files that are read from two different Python paths.
./data.dat ./a.py Path(__file__).parent / "data.dat" ./b/b.py Path(__file__).parent / .. / "data.dat"
More info
Contact support@mondaytech.com for more info.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Hashes for stonefish_code_shield-0.3.32-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3ec164a4c4d78ec74301420ab4151b042fbf75069de2c6e2f7c4343ed053f835 |
|
MD5 | b43593734d233c6b8a565093cc77a17f |
|
BLAKE2b-256 | ce28e86690170af48f75d22ce5a974732a914cb734d344607c3f373b2d006ed0 |