【问题标题】:How can I package a css file with a single module flask application with setuptools?如何使用 setuptools 将 css 文件与单个模块烧瓶应用程序打包?
【发布时间】:2018-10-14 01:27:34
【问题描述】:

给定一个这样组织的简单烧瓶应用程序:

app_repo/
--> flask_app.py
--> custom.css
--> setup.py
--> MANIFEST.in

我想打包它以在 PyPi 上发布,但在将 css 文件与应用打包在一起时遇到问题。

setup.py 文件如下所示:

from setuptools import setup

setup(
    name='myapp',
    version='1',
    py_modules=['flask_app'],
    data_files=[('', ['custom.css'])],
    entry_points={'console_scripts':
                  ['runapp = flask_app:app.run_server']},    
)

我还将 custom.css 文件包含在 MANIFEST.in 文件中。

在 flask_app.py 里面我有这样一行:

CSS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'custom.css')

这让我可以使用 Flask 的 send_from_directory 路由 css 文件。

从存储库目录开发应用程序并运行flask时,应用程序找到了css文件并且一切正常。但是当我使用 python setup.py sdist 打包应用程序时,css 文件没有放置在 flask_app.py 旁边,因此找不到。

在 unix 上,setup.py 中的 data_files 条目会导致安装的文件如下所示:

/usr/local/custom.css
/usr/local/lib/python3.6/site-packages/flask_app.py

但我想要以下内容,以便它反映存储库功能:

/usr/local/lib/python3.6/site-packages/custom.css
/usr/local/lib/python3.6/site-packages/flask_app.py

有没有办法拥有一个可以从入口点安装和运行的非打包单文件烧瓶应用程序,以确保 css 文件与安装 python 模块的目录位于同一目录中?

我知道我可以创建一个包,将应用程序和 css 文件放入包中,然后在 setup.py 文件中使用 package_data,但我正在寻找一个允许我不制作任何包的解决方案.

【问题讨论】:

    标签: python css flask setuptools


    【解决方案1】:

    将数据文件放入站点包目录有一个技巧,但它依赖于:

    1. 造轮子(所以源分发是不行的)
    2. bdist_wheel 的未记录行为,因此请注意此技巧可能会停止使用 wheel 包的未来版本。

    custom.css的目标目录改为/

    setup(
        data_files=[('/', ['custom.css'])],
        ...
    )
    

    为什么会这样?这是wheel 的未记录行为:通常,当您构建和安装源分发(例如,.tar.gz.zip)时,数据文件被放置到指定的目标目录中,例如@ 987654330@ 将覆盖系统的/etc/hosts 文件(假设您具有root 权限)。如您所见,系统损坏可能会变得非常糟糕,因此wheel 通过相对化绝对路径来避免这种情况:在上面的示例中,hosts 将不会写入/etc,而是写入/path/to/python/site-packages/etc。这就是技巧中使用的:应该写入系统根目录 (/) 的数据文件将写入站点包。

    但是,这在任何地方都没有记录,因此将来可能会发生变化。请密切关注this issue 以获得最终解决方案。

    另外,请记住,如果您构建源 dist 而不是轮子(通过 python setup.py sdist),则可以安装它,以便将 custom.css 写入系统根目录而不是站点包:

    $ pip install myapp --no-binary=myapp
    

    另一件事:您可以使用pkg_resources,而不是解析相对于flask_app.py 的文件路径,这样您就不需要摆弄路径字符串:

    from pkg_resources import Requirement, resource_filename
    CSS_PATH = resource_filename(Requirement.parse('myapp'), 'custom.css')
    

    【讨论】:

    • 这是一个非常有用的解决方法。我将等待,看看是否有其他选项可与 sdist 一起使用,并且在检查答案之前会更可靠。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 2019-02-17
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多