如何使用setuptools将带有单个模块瓶应用程序的css文件打包?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用setuptools将带有单个模块瓶应用程序的css文件打包?相关的知识,希望对你有一定的参考价值。

给出一个简单的烧瓶应用程序,其组织如下:

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']},    
)

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

在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模块的安装位置相同?

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

答案

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

  1. 构建轮子(因此源分发是禁止的)
  2. bdist_wheel的无证行为,所以要小心这个技巧可以停止使用未来版本的wheel包。

custom.css的目标目录更改为/

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

为什么这样做?这是wheel的未记录行为:通常,当您构建并安装源代码分发(例如,.tar.gz.zip)时,数据文件将被放置到指定的目标目录,因此例如data_files=[('/etc', ['hosts'])]将覆盖系统的/etc/hosts文件(假设您拥有root权限)。正如你所看到的,系统损坏可以变得任意不好,所以wheel通过相对化绝对路径来避免这种情况:在上面的例子中,hosts不会写入/etc,而是写入/path/to/python/site-packages/etc。这就是技巧中使用的内容:应该写入系统根目录(/)的数据文件将写入站点包。

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

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

$ pip install myapp --no-binary=myapp

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

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

以上是关于如何使用setuptools将带有单个模块瓶应用程序的css文件打包?的主要内容,如果未能解决你的问题,请参考以下文章

如何将整个 Vue 应用程序捆绑为单个 UMD 模块

如何将模块中的格式化子例程应用于跨工作簿的各种范围

如何将带有 chromium 的 web(webapp) 作为单个包分发?

如何以编程方式将 Play 2.4 模块的执行限制为单个主机?

如何安装 MySQLdb 包? (ImportError:没有名为 setuptools 的模块)

如何将 ZF2 单元/应用程序模块测试合并到单个调用中?