0

I have a Django web application, I want to install it for a client who doesn't want to use the internet so I have to install it locally on his pc, My question: what should I do to protect my source code. See that I have to put all my source code on his pc to be able to install the application, is there a possibility to encrypt the source code or to convert the django project into exe? thank you !

  • Not with python. Python has the attitude of "we are all adults here", and does not privatize. You can compile to an exe using pyinstaller, but the exe will just unpack everything to a temporary folder before running. You can obfuscate your code before deploying, making it really hard to understand using a tool such as this one: https://github.com/LeviBorodenko/lancer – James Jan 03 '22 at 08:18
  • I have used `Cython` to compile, you can try it, and there may be [problems](https://stackoverflow.com/questions/58797673/how-to-compile-init-py-file-using-cython-on-windows) (solved) on windows. – pppig Jan 03 '22 at 08:27
  • thank you for your comments i will try your solutions and see if it works thanks – INES SEHILI Jan 03 '22 at 08:57

1 Answers1

0

This is what I have used before. If the Cython compilation result meets your needs, you can use it for reference.

Directory Structure:
- project_path
- xx(new_path)
  - setup.py
Execute command:

If you encrypt the entire folder, put an __init__.py in the folder.

python setup.py build_ext -i

or 

python setup.py build_ext --inplace
Program:
from distutils.core import setup
from Cython.Build import cythonize
import shutil, os, sys, platform

if platform.system() == 'Windows':
    splice_str = "\\"
else:
    splice_str = "/"

# https://stackoverflow.com/questions/58797673/how-to-compile-init-py-file-using-cython-on-window/58803865#58803865
# Windows need to add
from distutils.command.build_ext import build_ext
def get_export_symbols_fixed(self, ext):
    names = ext.name.split('.')
    if names[-1] != "__init__":
        initfunc_name = "PyInit_" + names[-1]  # package name
    else:
        # take name of the package if it is an __init__-file
        initfunc_name = "PyInit_" + names[-2]  # filename
    if initfunc_name not in ext.export_symbols:
        ext.export_symbols.append(initfunc_name)
    return ext.export_symbols

# replace wrong version with the fixed:
build_ext.get_export_symbols = get_export_symbols_fixed


def get_allfile(old_dir, new_dir):
    import os
    # Get the root path of the current project
    root_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), old_dir)
    print(root_dir)
    exclude_folder = [".git", ".idea", "__pycache__", "static"]
    try:
        for root, dirs, files in os.walk(root_dir):
            # if not root.endswith('__pycache__'):
            if not [i for i in exclude_folder if i in root.split(splice_str)]:
                for file in files:
                    old_file = root + splice_str + file
                    if file.endswith('.py') and not file.startswith('00'):
                        add_commnet(old_file)
                        compile_code(old_file, old_file)
                    else:
                        current_dir = root.replace(root_dir, new_dir)
                        if not os.path.exists(current_dir):
                            os.mkdir(current_dir)
                        # Copy new file
                        print(current_dir, old_file)
                        shutil.copy(old_file, current_dir + splice_str + file)
        [os.remove(root + splice_str + file) for root, dirs, files in os.walk(root_dir) for file in files if file.endswith(".c")]

    except Exception as e:
        print(e)


# compile
def compile_code(name, filename):
    setup(
        name=name,
        ext_modules=cythonize(filename),
    )


def add_commnet(filename):
    with open(filename, 'r+', encoding='utf-8')as f:
        insert_data = '# cython: language_level=3\n'
        data = f.readlines()
        if not data or data[0] != insert_data:
            data.insert(0, insert_data)
        f.seek(0, 0)
        f.writelines(data)


if __name__ == '__main__':
    print(sys.argv)
    run_parms = sys.argv[3:]
    sys.argv = sys.argv[:3]
    if len(run_parms) >= 2:
        old_file = run_parms[0]
        new_file = run_parms[1]
    else:
        old_file = 'project_path'
        new_file = os.getcwd()
    get_allfile(old_file, new_file)
pppig
  • 1,215
  • 1
  • 6
  • 12