this post is under construction – I have the approaches here but need some time to also share the experience…

How to obscure some Python code from anyone running the code? I am no expert here but I have tried a few things and will give my steps and recommendations here.

Have a main.py with a simple helloworld FastAPI in this case. There is also an /error endpoint to see how much source code is returned in the logs.

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/error")
async def root():
    raise ValueError('all is wrong now')

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=3000)

Install fastapi and uvicorn with pip and run the code with:

python main.py

And find the API on http://0.0.0.0:3000.

Option 1: Compile with CPython

Compile to CPython:

python -m compileall .

Now run with:

python __pycache__/main.cpython-310.pyc

These files .pyc can be decompiled, so a developer with some (or little?) effort can read the source code.

Option 2: Obfuscate with PyArmor

There are some obfuscate projects to make it hard to read the source code, such as PyArmor:

pip install pyarmor

and obfiscate the code base:

pyarmor gen main.py
python dist/main.py

It works great, but some info from the files can still be retrieved from memory.

Option 3: Cythonizing

Here cythonizing is just compiling to Cython.

pip install cython

Have a compile.py with the compile options:

from distutils.core import setup

from Cython.Build import cythonize

setup(
    ext_modules=cythonize(
        module_list=["main.py"],
        compiler_directives=dict(
            c_string_encoding="utf-8",
            language_level=3,
        ),
    )
)

And compile:

python compile.py build_ext

You can import and run app from the so file, or you can run directly with uvicorn:

uvicorn main:app

Conclusion

Give me some time to bring this to a conclusion.