将 JS 文件移动到 site-packages/notebook/static 的潜在不明智之处
the potential inadvisability of moving JS files to site-packages/notebook/static
我有一个 setup.py 配置可以工作,但感觉非常糟糕。
它适用于一个小部件(通过 ipywidgets.DOMWidget
继承),其 JS 代码是多部分的并且在所有 CDN 中都是错误的——所以我不能简单地 require(['www.some_cdn.com/foo'])
在注入浏览器的 JS 中。
结果 post-安装我得到 setup.py 将所需的文件复制到 site-packages/notebook/static
,允许 JS require(['/static/jsfolder/some.entry.point.js'])
工作(下面的代码)。
我想一定有一个标准的方法可以做到这一点,特别是因为这个 hack 只适用于源代码分发而不是 wheel,但我莫名其妙地似乎无法找到“官方”方法。我找不到的文档在哪里?
import os
import importlib.util
from distutils.dir_util import copy_tree, remove_tree
from distutils import log
def post_install():
"""
Moves the jsfolder folder contents to site-packages/notebook/static
"""
log.info('copying files over to site-packages/notebook/static')
init_of_notebook = importlib.util.find_spec('notebook').origin
copy_tree('jsfolder', os.path.join(os.path.dirname(init_of_notebook), 'static', 'jsfolder'))
# are we in a github or a source package?
if os.path.exists(os.path.join('.git')) and not os.path.exists('PKG-INFO'):
# we are in a git repo, so the usual fluff for pypi
with open('README.md') as f:
readme = f.read(). # etc.
# any pre-packaging tinkering would probably happen here
# ...
setup(...,
include_package_data=True, # MANIFEST.in has `recursive-include * *.png *.js *.css *.gif *.txt` or `graft jsfolder/**` etc.
)
post_install()
好奇路人的解释性脚注
这个问题非常技术性,所以为了防止未来的用户偶然发现顺便说的东西,我想我会扩展它——只是不要复制黑客!
在 Jupyter notebook 中,你可以 not 在 URL 中指定的根目录下提供任何东西(幸运的是),除了特殊路由 /static
以预期的 MIME 类型提供 site-packages/notebook/static
中的文件,static/contents
中的文件除外,它们是 text/html
。 site-packages
是pip安装包一般放的文件夹。
如果有 MANIFEST.in
文件,setup
中的 include_package_data=True
参数将指定的文件复制到存储库根目录中的源分发,而不需要 __init__.py
在每个文件夹中不像更干净但更费力的 package_data
参数。
这里有几个post执行代码预安装和post-install涉及继承from setuptools.command.install import install
。截至 2022 年,python setup.py install
已弃用,取而代之的是 pip install .
,其中许多无效。
此外,任何 log.info
都比 print
好,因为它会显示为 pip install foo.tar.gz -v
。
official-ish 解决方案似乎是 https://github.com/jupyter/jupyter-packaging
这用于 https://github.com/jupyter-widgets/widget-cookiecutter
中的示例
from jupyter_packaging import wrap_installers, npm_builder
from types import FunctionType
from typing import Dict
builder:FunctionType = npm_builder()
cmdclass:Dict[str,type] = wrap_installers(pre_develop=builder, pre_dist=builder)
setup(cmdclass=cmdclass, ...))
与我的 hack 不同,他们通过 nodejs 包管理器安装 js。即,
npm_builder
是一个工厂,它...
import inspect
print(inspect.getsource(npm_builder))
以下:
def npm_builder(
path=None, build_dir=None, source_dir=None, build_cmd="build", force=False, npm=None
):
...
npm_cmd = npm
...
def builder():
...
npm_cmd = npm
...
run(npm_cmd + ["install"], cwd=node_package)
if build_cmd:
run(npm_cmd + ["run", build_cmd], cwd=node_package)
我有一个 setup.py 配置可以工作,但感觉非常糟糕。
它适用于一个小部件(通过 ipywidgets.DOMWidget
继承),其 JS 代码是多部分的并且在所有 CDN 中都是错误的——所以我不能简单地 require(['www.some_cdn.com/foo'])
在注入浏览器的 JS 中。
结果 post-安装我得到 setup.py 将所需的文件复制到 site-packages/notebook/static
,允许 JS require(['/static/jsfolder/some.entry.point.js'])
工作(下面的代码)。
我想一定有一个标准的方法可以做到这一点,特别是因为这个 hack 只适用于源代码分发而不是 wheel,但我莫名其妙地似乎无法找到“官方”方法。我找不到的文档在哪里?
import os
import importlib.util
from distutils.dir_util import copy_tree, remove_tree
from distutils import log
def post_install():
"""
Moves the jsfolder folder contents to site-packages/notebook/static
"""
log.info('copying files over to site-packages/notebook/static')
init_of_notebook = importlib.util.find_spec('notebook').origin
copy_tree('jsfolder', os.path.join(os.path.dirname(init_of_notebook), 'static', 'jsfolder'))
# are we in a github or a source package?
if os.path.exists(os.path.join('.git')) and not os.path.exists('PKG-INFO'):
# we are in a git repo, so the usual fluff for pypi
with open('README.md') as f:
readme = f.read(). # etc.
# any pre-packaging tinkering would probably happen here
# ...
setup(...,
include_package_data=True, # MANIFEST.in has `recursive-include * *.png *.js *.css *.gif *.txt` or `graft jsfolder/**` etc.
)
post_install()
好奇路人的解释性脚注
这个问题非常技术性,所以为了防止未来的用户偶然发现顺便说的东西,我想我会扩展它——只是不要复制黑客!
在 Jupyter notebook 中,你可以 not 在 URL 中指定的根目录下提供任何东西(幸运的是),除了特殊路由 /static
以预期的 MIME 类型提供 site-packages/notebook/static
中的文件,static/contents
中的文件除外,它们是 text/html
。 site-packages
是pip安装包一般放的文件夹。
如果有 MANIFEST.in
文件,setup
中的 include_package_data=True
参数将指定的文件复制到存储库根目录中的源分发,而不需要 __init__.py
在每个文件夹中不像更干净但更费力的 package_data
参数。
这里有几个post执行代码预安装和post-install涉及继承from setuptools.command.install import install
。截至 2022 年,python setup.py install
已弃用,取而代之的是 pip install .
,其中许多无效。
此外,任何 log.info
都比 print
好,因为它会显示为 pip install foo.tar.gz -v
。
official-ish 解决方案似乎是 https://github.com/jupyter/jupyter-packaging 这用于 https://github.com/jupyter-widgets/widget-cookiecutter
中的示例from jupyter_packaging import wrap_installers, npm_builder
from types import FunctionType
from typing import Dict
builder:FunctionType = npm_builder()
cmdclass:Dict[str,type] = wrap_installers(pre_develop=builder, pre_dist=builder)
setup(cmdclass=cmdclass, ...))
与我的 hack 不同,他们通过 nodejs 包管理器安装 js。即,
npm_builder
是一个工厂,它...
import inspect
print(inspect.getsource(npm_builder))
以下:
def npm_builder(
path=None, build_dir=None, source_dir=None, build_cmd="build", force=False, npm=None
):
...
npm_cmd = npm
...
def builder():
...
npm_cmd = npm
...
run(npm_cmd + ["install"], cwd=node_package)
if build_cmd:
run(npm_cmd + ["run", build_cmd], cwd=node_package)