[英]Packaging a Python project and its associated IPython magic extension
I am in the process of deploying to Pypi a Python project, let's call it foobar
.我正在向 Pypi 部署一个 Python 项目,我们称之为
foobar
。 I would like to distribute it with a shell command and an IPython magic command.我想用 shell 命令和IPython 魔术命令分发它。 I use Poetry, and the relevant part of my
.toml
configuration file is:我使用 Poetry,我的
.toml
配置文件的相关部分是:
[tool.poetry.scripts]
foobar = 'foobar.cli:main'
foobar_magic = 'foobar.magic:load_ipython_extension'
After uploading this to TestPypi and installing it with pip
, the shell command ( foobar
) works as expected.将其上传到 TestPypi 并使用
pip
安装后, shell 命令( foobar
)按预期工作。 However, executing %load_ext foobar_magic
in a Jupyter Notebook fails with:但是,在 Jupyter Notebook 中执行
%load_ext foobar_magic
失败并显示:
ModuleNotFoundError: No module named 'foobar_magic'
According to the documentation :根据文档:
You can put your extension modules anywhere you want, as long as they can be imported by Python's standard import mechanism.
你可以把你的扩展模块放在你想要的任何地方,只要它们可以被 Python 的标准导入机制导入。
Under the same notebook, I have verified that !foobar
and import foobar
both work.在同一个笔记本下,我已经验证
!foobar
和import foobar
都可以工作。 How can I make foobar_magic
be found too?我怎样才能找到
foobar_magic
呢?
Moreover, although I'm not there yet, I guess the suffix of the entry point is wrong too.而且,虽然我还没到那里,但我猜入口点的后缀也是错误的。 Indeed, the function I specify after the
:
will be called with no arguments, but the function load_ipython_extension()
expects an IPython instance.实际上,我在
:
之后指定的 function 将在没有 arguments 的情况下被调用,但 function load_ipython_extension()
需要一个 IPython 实例。
So I feel completely lost, and can't find any relevant documentation for deploying IPython Notebook extensions.所以我完全迷失了方向,找不到任何部署 IPython Notebook 扩展的相关文档。
Edit 1. %load_ext foobar.magic
unexpectedly works, and the magic %foobar
does not complain about the arguments.编辑 1.
%load_ext foobar.magic
出人意料地工作,魔术%foobar
并没有抱怨 arguments。 I don't understand why, and why it is %foobar
and not %foobar_magic
as declared.我不明白为什么,为什么它是
%foobar
而不是声明的%foobar_magic
。
Edit 2. the foobar_magic =...
stuff is ignored or useless.编辑 2.
foobar_magic =...
东西被忽略或无用。 Suppressing it has no consequence on %load_ext foobar.magic
.抑制它对
%load_ext foobar.magic
没有影响。 I think the latter invocation might be ok.我认为后一种调用可能没问题。 But it's a little annoying not to understand what's going on.
但是不明白发生了什么有点烦人。
I finally found a workaround:我终于找到了解决方法:
foobar_magic =...
of my .toml
..toml
的foobar_magic =...
行。 Move the contents of foobar/magic.py
to foobar/__init__.py
(originally empty), guarded with the following two lines:将
foobar/magic.py
的内容移动到foobar/__init__.py
(原来是空的),用以下两行保护:
import sys if "ipykernel" in sys.modules: # magic stuff
This file being executed each time the module is imported, it is now enough to do (under a notebook):每次导入模块时都会执行此文件,现在就足够了(在笔记本下):
%load_ext foobar
The guard ensures the magic stuff is executed if and only if foobar is imported from IPython.当且仅当从 IPython 导入 foobar 时,守卫确保执行神奇的东西。
This does not answer my original question, and I still do not fully understand how these entry points are supposed to work, but I am happy with the actual result.这不能回答我最初的问题,我仍然不完全理解这些入口点应该如何工作,但我对实际结果感到满意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.