This is an example application for demonstrating how to protect python source code and distribute package.
(If you want to see my reference, please jump to last section. I will not explain why questions in this Readme.)
Packaging is grouping python codes of project into a module as blackbox.
Your package will be able to:
- install and manage as pip library.
- specify as a dependency for another package.
- add and distribute with documentation.
With Cython, in advanced, your python code will be compiled to object files (.pyd in Windows, .so in Linux).
And it's difficult to reverse your release.
I will go step by step from structure of this example, how to setup, build, and verify your result.
A project that has app package will look like:
root project directory
├── app <-- application folder
│ ├── includes <-- include folder (an example folder that you want to copy to wheel)
│ ├── core.py <-- python source code
│ ├── main.py <-- python source code
│ └── __init__.py <-- package mandatory file
├── example2.py <-- script for testing *app*
└── setup.py <-- script for packaging
└── setup_cython.py <-- Run it, instead of above script, to package with Cython
-
__init__.py: Folder of an application must contain __init__.py file. This file can be blanked in simple project.
But for a Cython packaging, you have to explicitly export your application modules there.from __future__ import print_function from . import main from .core import greeting from .main import hello from .main import hello2 print('Hello from __init__')
In above __init__.py file, I explicitly declare three functions that my app will provide.
These functions are implemented in another python files. -
setup.py: File setup.py is directive to build your package. An simple setup file is ...
# coding: utf-8 import os from setuptools import setup, find_packages setup( name='app', version='0.1.0', packages=find_packages() )
-
example2.py: in this file, I include app as a library. And I use functions in app.
- setup_cython.py: this file will be used, instead of setup.py, when you need to hide your python code.
It contains overrided functions of Cython utilities.
This file is required to be modified, to adapt with each your application. (Please read this file carefully before use for other application)
You can also see another example of folder structure in link .
Your application code may be organized different with above structure. Steps will different with this guide.
$ git clone https://github.com/viettoan151/demo-source-protect-wheel.git
$ cd demo-source-protect-wheel
$ virtualenv .venv --python=python3.6
$ source .venv/bin/activate
$ pip3 install Cython
In simple, you just run setup.py script to generate wheel files.
$ rm -rf app.egg-info dist build
$ python3 setup.py bdist_wheel
Your wheel is generated in dist/, name app-x.x.x-py3-none-any.whl
(From my understanding x.x.x is version of app, py3 is python3 compatibility, none-any is independent from OS and architecture)
But above wheel does not hide your python code. Unzip this wheel and check yourself.
Let's try the next script, setup_cython.py:
$ rm -rf app.egg-info dist build
$ python3 setup_cython.py bdist_wheel
Your wheel is generated in dist/, name app-x.x.x-cp36-cp36m-linux_x86_64.whl
(Name is different with above! Now, this wheel is only compatible with python 3.6, Linux OS, and x86_64 architecture)
OK, you already hide your code . Go next step to verify it!
Unzip your wheel:
$ unzip dist/app-0.1.0-cp36-cp36m-linux_x86_64.whl -d dist/app
In unzip folder, verify there is no python source code
$ tree dist/app
dist/app
├── app
│ ├── core.cpython-36m-x86_64-linux-gnu.so
│ ├── includes
│ │ ├── example.bin
│ │ └── example.py
│ ├── __init__.cpython-36m-x86_64-linux-gnu.so
│ ├── __init__.py
│ └── main.cpython-36m-x86_64-linux-gnu.so
└── app-0.1.0.dist-info
├── METADATA
├── RECORD
├── top_level.txt
└── WHEEL ...
And try to run example in extracted folder:
$ cp example2.py dist/app
$ cd dist/app
$ python3 -m example2
Hello from __init__
Test 0: greeting function
--> Greeting
Test 1: hello2 functiond
--> Hello world2
Test done
Python Guideline
Python Sample project
Simple to complicated with Cython
Advance in Cython