Typically, PyXLL is used to deploy Python toolkits and functionality to Excel users within the same organization. Even so, it can sometimes be a requirement that the end users do not have access to the Python source code.
PyXLL works by loading your Python runtime into Excel, and so the only requirement for PyXLL is that your Python modules are able to be imported. With Python, a module's original source code is not always needed for the module to be imported.
Note: If you are looking to build a distributable add-in to deploy to users outside of your organization this will likely be outside of what's allowed in the Software License Agreement and you should contact info@pyxll.com to check. All users of the PyXLL add-in must be licensed, including all end users and not just developers.
Compiled Python Byte Code Modules
A plain Python module is a ".py" file, containing the Python code as plain text. When Python imports a ".py" file, it first compiles it into byte code -- Python can also import a module that only contains pre-compiled byte code, which is saved as a ".pyc" file. These compiled Python byte code ".pyc" files can be distributed to your users without the source ".py" files and Python will still be able to import them.
One common technique is to use the standard Python tool "compileall" (https://docs.python.org/3/library/compileall.html) to compile your source .py files into Python byte code .pyc files. These .pyc files can still be imported by Python, and so can be used by PyXLL, without needing the original .py source files. One important caveat is that you must use the same version of Python to compile the .pyc files as the version of Python that is going to import them.
While it is possible to decompile Python byte code files and so this solution does not guarantee perfect security (no solution will) it is often considered a good solution.
Compiled Native Extension Modules
If you have some part of your code which is especially sensitive, one solution can be to compile just that part of the code into a native Python extension module.
A native Python extension module (.pyd file) is a binary file, typically built from a C or C++ project. Compiled native extensions are more difficult to reverse engineer and offer a better level of protection for sensitive algorithms that compiled Python byte code.
Because PyXLL is just using your existing Python runtime, it can of course import these .pyd extension modules. They are more difficult to write and typically require some C and/or C++ experience.
Tools like Cython (https://cython.org/) can help by translating plain Python code to C code, which can then be compiled into a native Python extension module.
Converting all of your code to C and compiling everything is usually too much work, but if part of your code is very sensitive then this can be a good solution (and can be combined with using compiled Python bytes code modules for the rest of your code).
Code Obfuscation
Instead of distributed compiled Python byte code files or compiled extension modules, another solution is to make the code unreadable, but in such a way that the Python interpreter can still read it. The process of making the code unreadable (hard to read) is called code obfuscation.
There are various other 3rd party tools for obfuscating Python source code that you can search for online, but there is not one that we recommend over any other - so long as the obfuscated modules can be imported by Python, you will be able to use them with PyXLL.
One thing to note is that if as part of obfuscating the Python code, and functions exposed to Excel are renamed, the function names in Excel will also change! The "name" kwarg to @xl_func can be used to set the Excel name explicitly, rather than using the Python function name.