V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
yinlei212
V2EX  ›  Python

[困惑] 写好的 Python 应用如何分发?

  •  
  •   yinlei212 · 2024-01-04 09:48:43 +08:00 · 4147 次点击
    这是一个创建于 391 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景: 我写好了一个应用的所有代码,我需要进行分发给我的客户,但是我不想让他们得到源码。请问如何操作?, 有没有全平台统一方案(win/mac/linux)?

    已知的分发场景:

    1. 源代码分发,直接上传 pypi ,或者 git 让使用。(源码分发不合适)
    2. windows 的话打包成 exe 进行分发(但是这个仅仅只是 windows 平台的)。
    第 1 条附言  ·  2024-01-05 14:20:15 +08:00
    总结下:
    Python 没有一个语言级别的代码混淆解决方案,就 Pydantic 而言 是鼓励代码开源的。

    总结上面 V 友们的方案:
    1. pyinstaller 打包, -- 需要各平台单独打包。有反编译风险。
    2. 用 Cython 将 py 编译成 .pyd/.so ->在用 pyinstaller 进行打包 。 -- 各平台单独打包分发、反编风险小
    3. pyarmor 是一个专业混淆代码库,也是编译成字节码然后用-> pyinstaller 打包分发 ---- 各平台单独打包分发、反编风最小
    4. Nuitka 直接使用 Clang 进行编译运行。


    我的结论:
    1. 就 安全性而言使用 3 方案 pyarmor 比较好;
    2. 就 简单易用性而言 4 方案 Nuitka 是不错的方案。

    如以上理解有误请斧正。
    33 条回复    2024-01-08 21:28:22 +08:00
    shinession
        1
    shinession  
       2024-01-04 09:57:46 +08:00
    pyinstaller+1, 环境什么的都集成进去了, 方便快捷
    locoz
        2
    locoz  
       2024-01-04 10:00:37 +08:00 via Android
    前几年的 pycon 我记得有一届里有人介绍了个他的产品,专门做 python 代码打包+混淆/加密的,忘记叫啥了,你可以翻一下
    Etuloser
        3
    Etuloser  
       2024-01-04 10:13:50 +08:00
    pyinstaller 分别打 win 平台和 linux 平台的包
    fzls
        4
    fzls  
       2024-01-04 10:27:31 +08:00
    用 pyinstaller 就好了
    Lighthughjiajin
        5
    Lighthughjiajin  
       2024-01-04 10:43:24 +08:00
    pyinstaller 能保护源码吗?
    009694
        6
    009694  
       2024-01-04 10:48:58 +08:00 via iPhone
    核心源码想要保护要么用 c 这类编译成动态库用 python 调,要么服务化。
    myxingkong
        7
    myxingkong  
       2024-01-04 10:59:10 +08:00   ❤️ 2
    可以使用 Cython 将 Python 源文件 编译成 动态链接库(.pyd|.so),再使用一个入口文件(不需要编译)去调用你的 app 的启动方法。

    main.py
    ```python
    import sys
    import my_app

    sys.exit(my_app.run())
    ```

    main.py 可以使用 Pyinstaller 单独打包成可执行文件,然后把使用 Cython 编译好的 动态链接库 放到可执行文件的同级目录下,就可以运行了。
    cooljiang
        8
    cooljiang  
       2024-01-04 11:08:35 +08:00
    程序整体用 pyinstaller 的打包的分发的话会有被反编译的风险(很容易被反编译)
    结合楼上说的用 Cython 将 py 编译成动态链接库(.pyd/.so)外,楼主如果想进一步保护 py 分发程序,还可以考虑针对 Python 解释器单独进行加密混淆。
    liuhai233
        9
    liuhai233  
       2024-01-04 11:10:07 +08:00
    做成 saas 服务 ^-^
    lingeo
        10
    lingeo  
       2024-01-04 11:11:15 +08:00
    cython 可以编译成.so ,但是就是没法跨平台,你得分开编译。
    ohayoo
        11
    ohayoo  
       2024-01-04 11:51:24 +08:00
    @locoz #2 是的,你说的这个 我也有印象
    Abbeyok
        12
    Abbeyok  
       2024-01-04 12:39:10 +08:00
    pyarmor
    bthulu
        13
    bthulu  
       2024-01-04 13:51:09 +08:00
    编译成 native 就行了
    orcal
        14
    orcal  
       2024-01-04 14:25:55 +08:00
    Nuitka 吧,简单高效全平台
    airchaoz
        15
    airchaoz  
       2024-01-04 14:31:30 +08:00
    @orcal 之前用过这个,打包没有 pyinstaller 方便,不知道现在怎么样了
    orcal
        16
    orcal  
       2024-01-04 14:41:14 +08:00
    还是没有 pyinstaller 方便哈哈
    dianso
        17
    dianso  
       2024-01-04 14:52:34 +08:00
    太繁琐,依赖,库

    我已经全面转 go

    就是看在开发迅速,编译单文件,不依赖 libc ,直接全平台分发
    Alicewish
        18
    Alicewish  
       2024-01-04 15:14:19 +08:00
    nuitka ,如果有复杂点的库那么打包成功率比 pyinstaller 高。
    mnsw
        19
    mnsw  
       2024-01-04 15:32:07 +08:00
    @shinession #1 但这个只能本平台打包本平台的吧?不能跨平台
    lybcyd
        20
    lybcyd  
       2024-01-04 15:41:25 +08:00
    单靠 pyinstaller 不行,这个反编译很简单的,想要保护源代码肯定还要混淆加密
    JavaGym
        21
    JavaGym  
       2024-01-04 15:57:35 +08:00
    pywebio 做成网页
    hanyu2pomelo
        22
    hanyu2pomelo  
       2024-01-04 16:10:06 +08:00
    pyarmor 加密后,打包个镜像
    xxq2334
        23
    xxq2334  
       2024-01-04 17:00:46 +08:00 via Android
    @Alicewish 这个好
    GeekGao
        24
    GeekGao  
       2024-01-04 21:09:15 +08:00
    @locoz pyarmor
    usiantein
        25
    usiantein  
       2024-01-05 10:08:18 +08:00   ❤️ 1
    这个主题我有相关实践经验。我们之前做的一个 Python package 也是需要分发到客户的机器上安装,为了保护 python 源代码,我们最后采用的方案是 Cython 编译:将 py 文件编译成 so 二进制,最后 setup.py 打包出来的 wheel 文件中,都是 so 文件。具体可以参考这个 blog: https://art-vasilyev.github.io/posts/protecting-source-code/
    yinlei212
        26
    yinlei212  
    OP
       2024-01-05 14:09:51 +08:00
    总结下:
    Python 没有一个语言级别的代码混淆解决方案,就 Pydantic 而言 是鼓励代码开源的。

    总结上面 V 友们的方案:
    1. pyinstaller 打包, -- 需要各平台单独打包。有反编译风险。
    2. 用 Cython 将 py 编译成 .pyd/.so ->在用 pyinstaller 进行打包 。 -- 各平台单独打包分发、反编风险小
    3. pyarmor 是一个专业混淆代码库,也是编译成字节码然后用-> pyinstaller 打包分发 ---- 各平台单独打包分发、反编风最小
    4. Nuitka 直接使用 Clang 进行编译运行。


    我的结论:
    1. 就 安全性而言使用 3 方案 pyarmor 比较好;
    2. 就 简单易用性而言 4 方案 Nuitka 是不错的方案。

    如以上理解有误请斧正。
    akaHenry
        27
    akaHenry  
       2024-01-05 17:08:35 +08:00
    @yinlei212 使用 Cython 单独编译一个 .so 的二进制授权+验证库:

    1. 可以是填授权码+验证的, 也可以是发 HTTP + 在线检查的.
    2. 你的 main() 每次都检查 .so 里的 授权方法, 如果失败, 就不让用.


    做到这样, 基本就低成本保护了. 大部分代码, 都没啥保护价值. 只保护最核心的部分+核心链路.
    usiantein
        28
    usiantein  
       2024-01-05 20:05:12 +08:00
    @yinlei212 第 2 点中,pyinstaller 不是必要的,只需要写好 setup.py 文件,用 python3 setup.py bdist_wheel 就能打包,结合一些 CI 工具( e.g., GitHub Action ),可以针对 win/mac/linux 平台打出对应的分发包。
    usiantein
        29
    usiantein  
       2024-01-05 20:10:55 +08:00
    @yinlei212 另外,除了用 Cython 编译每个 .py 源文件外,我们还在整个 package 的入口( i.e., __init__.py )引入了 HTTP 认证,只要用户需要 import 我这个 package ,就需要进行 HTTP 认证,这样当我们不想让客户继续使用这个 package 时,将 HTTP 认证的结果返回为 False 就行了。
    qixinwuchen
        30
    qixinwuchen  
       2024-01-05 23:38:53 +08:00
    借楼问下,op 说的 python 应用指的 python 脚本? 还是 python web 项目? 如果想对使用 django 框架开发的 web 项目进行加密,上面的方式能做到吗?
    qixinwuchen
        31
    qixinwuchen  
       2024-01-05 23:43:31 +08:00
    @usiantein 请问,假如是复杂的 django web 项目, 能用这种方式加密吗? 对每个 py 文件打包后各个 package 的依赖关系还能保持吗
    usiantein
        32
    usiantein  
       2024-01-07 10:45:24 +08:00
    @qixinwuchen 我不太明白你这里所说的「 package 的依赖关系」具体指的是什么,Cython 编译这个技术是针对 Python 语言的,我理解跟什么类型的 web 项目无关。你也可以这么理解,编译后和编译前,源代码的调用方式、启动方式没有任何改变,只是所有的 .py 文件被替换成功能一致的 .so 二进制文件。
    iorilu
        33
    iorilu  
       2024-01-08 21:28:22 +08:00
    注意是 python 社区公认, python 就应该开源, 所以核心大佬们从来不愿意研究什么加密, 混淆, 打包二进制之类的事情

    目前相对还是 pyinstaller 算成熟的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   701 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:46 · PVG 05:46 · LAX 13:46 · JFK 16:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.