简体   繁体   English

打包 Python 项目及其关联的 IPython 魔术扩展

[英]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.在同一个笔记本下,我已经验证!foobarimport 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:我终于找到了解决方法:

  1. Delete the line foobar_magic =... of my .toml .删除我的.tomlfoobar_magic =...行。
  2. 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
  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM