I have a Flask application application that I run with uWSGI. My clients have access to the server where the app runs.
How can I protect or hide my source code?
Edit: I found that you can embed an app in uWSGI by building it from source, but that seems far fetched.
True - if someone wants it badly enough, the only way to truly secure your algorithms is not to hand them out. But, reality is that code is hard to understand anyway. Often, just not documenting code is enough to discourage. There are some techniques, however, and your effort varies with how secure they are. Some approaches that come to mind are.
Compile to bytecode: I've seen it done in the wild, there was company that made a Python email client for Linux / Outlook. I recall that it was obfuscated through a compiled distribution. You'd have to research the proper tool.
Obfuscate at a per-script level: Check out the pyminifier tool. It can make your scripts pretty near impossible to read (but it can be reversed with reasonable effort)
Use an advanced obfuscator: Look at pyarmor. It is a lot more complex and will be harder to implement -- but it looks like it would get the job done.
Open source it. Seems counter intuitive -- but algorithms are rarely the most valuable aspect of code. Having the skill, time, resources to understand and maintain it is. It is very likely that it doesn't matter if anyone sees your code. If you are giving a good service to your customer, they generally have much better things to do than to take on your code base. There are plenty of enterprise companies making a living from open source software (eg. Startburst, 2nd Quadrant.)
(Example code obfuscated using pyminifier)
import argparse
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐤡=range
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ枇=int
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𧌾=print
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆﶾ=argparse.ArgumentParser
import sys
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𑆉=sys.argv
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𞤌=sys.stdout
import logging
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ닸=logging.basicConfig
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𧄱=logging.DEBUG
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ柚=logging.INFO
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ䔎=logging.getLogger
from demo import __version__
__author__="Steve Jackson"
__copyright__="Steve Jackson"
__license__="mit"
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐪕=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ䔎(__name__)
def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡈲(n):
assert n>0
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ関,𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𒂻=1,1
for i in 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐤡(n-1):
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ関,𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𒂻=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𒂻,𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ関+𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𒂻
return 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ関
def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐲍(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮):
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆﶾ(description="Just a Fibonacci demonstration")
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.add_argument("--version",action="version",version="demo-day {ver}".format(ver=__version__))
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.add_argument(dest="n",help="n-th Fibonacci number",type=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ枇,metavar="INT")
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.add_argument("-v","--verbose",dest="loglevel",help="set loglevel to INFO",action="store_const",const=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ柚)
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.add_argument("-vv","--very-verbose",dest="loglevel",help="set loglevel to DEBUG",action="store_const",const=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𧄱)
return 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆݻ.𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐲍(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮)
def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐮑(loglevel):
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𗰆="[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ닸(level=loglevel,stream=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𞤌,format=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𗰆,datefmt="%Y-%m-%d %H:%M:%S")
def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆﯜ(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮):
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮=𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐲍(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮)
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐮑(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮.loglevel)
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐪕.debug("Starting crazy calculations...")
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𧌾("The {}-th Fibonacci number is {}".format(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮.n,𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡈲(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𡐮.n)))
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𐪕.info("Script ends here")
def 𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆܪ():
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆﯜ(𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆ𑆉[1:])
if __name__=="__main__":
𒉁ۻ𨠬𧑔ﲮᆖ𪿺𖢞ﻆܪ()
# Created by pyminifier (https://github.com/liftoff/pyminifier)