DEV Community

Dongchao (Alan) Chen
Dongchao (Alan) Chen

Posted on

What I learned from python app distribution

Problem

Recently, we need to distribute our python Flask application in docker container. Initially, I was using hatch to build/test our application, by default, hatch build will produce a source distribution and a wheel. But we do not want to distribute our source code in our docker container, how can we protect our intellectual property?

Possible Options and Challenges

Here are a few options that discussed in python wiki - How do you protect Python source code?, in summary, you have the following options

  • Use compiled bytecode
    • The generated .pyc files are not portable between different versions of Python
    • You can still decompyle the pyc file to reverse engineering.
  • Executable creators (or Installers)
  • Software as a Service
    • Deploy the way like Google did.
    • deployment only on locked down VMs (client only has API acces, no console access to host).
  • Python Source Code Obfuscators
    • Use the tool like Pyarmor
    • But I am worried about the performance
  • Use of modified docker container that has no shell environment or other mechanisms to prevent access to the files within docker container.
    • no shell in docker looks so challenge since we need bash to execute the program, allocate job tasks, etc.
    • lock file permissions may be possible

Solution

  • Besides the source code, when you build a distribution package, you can use wheel or egg format, here is a good summary of Wheel vs Egg
  • When you use $ python setup.py bdist_egg --exclude-source-files can help you remove source files in the distributed package, but egg file you need to use easy_install to install, which is deprecated in setuptools now, the recommended way is using pip which need to install wheel file.
  • thanks to stackoverflow answer - how to exclude source code from beist_wheel python
python setup.py bdist_egg --exclude-source-files
wheel convert dist/package-*.egg -d dist
Enter fullscreen mode Exit fullscreen mode

which will generate dist/package-*-py38-none-any.whl if you did not define platform details.

  • finally, you can use pip install package-*-py38-none-any.whl to install the package which only contains the pyc files
  • you can use pip show <package> to check where your package get installed and also go though all folders to double confirm no source code *.py files exist.

References

Top comments (5)

Collapse
 
philipstarkey profile image
Phil Starkey

If you really want to protect your code you should consider writing it in cython and compiling it to a (platform dependent) .pyd file that can be imported into standard Python using the usual import syntax.

Collapse
 
dongchaochen profile image
Dongchao (Alan) Chen

Agree and thanks, I will go to give a try.

Collapse
 
richard_scott profile image
Richard Scott • Edited

Have you heard about: SOURCEdefender - advanced encryption protecting your Python codebase

Collapse
 
sdabhi23 profile image
Shrey Dabhi

I want to use PyArmor with Flask, but am not able to find any documentation on it. It is the same as with normal python scripts? Can you please point me into the right direction?

Collapse
 
nurdturd_12 profile image
Sheldon Rupp

Hello! It seems to be actually yeah. Just check out the PyArmor docs. Been doing stuff in it recently hit me up if you need any more pointers.