Package: jupyter-kernel-hook
Jupyter Kernel HookA simple way to turn your package into a Jupyter server extension that automatically preload into an IPython kernel.You can install this package viapip install jupyter-kernel-hook.ExampleAdd the following to your package's__init__.py:# my_package/__init__.pydef_jupyter_server_extension_paths():return[{"module":"my_package"}]defload_jupyter_server_extension(nb_app):fromjupyter_kernel_hookimportcreate_startup_scriptcreate_startup_script(nb_app,"my_package")Now when a user runsjupyter serverextension enable --py my_package, your package will be enabled as a server extension that is preloaded within every IPython kernel.  So now the user does not need to runimport my_packageto run it for each kernel session.FeaturesSimplicity.jupyter_kernel_hookdoes for you the annoying part of preloading your packages in a sane way.Intuitive behavior.Your startup script can be enabled and disabled throughjupyter serverextension enable --py my_package.When your extension isenabled, it will preload (and invoke an optional function call) in each IPython kernel.When your extension isdisabled, it is never preloaded / imported.Performance.Everything is lazy-loaded to reduce overhead and required dependencies. (jupyter_kernel_hookis imported in various contexts-- the server starting up, kernels starting up-- and different contexts require different things.)AdvancedPreload IPython ExtensionJupyter Kernel Hook is used to make Jupyter server extensions. A natural use case, though, is to turn a nativeIPython extensioninto a Jupyter Notebook extension, such as those that add cell magic to the IPython runtime.You can call aload_ipython_extensionfunction like this:# my_package/__init__.pyfrom.coreimportMyPackageMagicsdef_jupyter_server_extension_paths():return[{"module":"my_package"}]defload_jupyter_server_extension(nb_app):fromjupyter_kernel_hookimportcreate_startup_scriptcreate_startup_script(nb_app,"my_package:load_ipython_extension(ip)")defload_ipython_extension(ip):ip.register_magics(MyPackageMagics)And the startup script will make sure that theipobject is defined.(Note: You can run any arbitrary function call, not justload_ipython_extension.)Add Package to Kernel's Global NamespaceBy default, the global namespace of the IPython kernel is untouched by the generated script.You can, however, add the package to the global namespace like this:create_startup_script(nb_app,"my_package:load_ipython_extension(ip)",add_to_globals=True)In this case,my_packagewill be available in the IPython kernel's globals.(Warning: This doesn't work for nested packages/modules at the moment. Do that at your own risk.)Jupyter Entry Point inSetup.pyThis is a Jupyter thing in general, but it's quite handy for your packages.Basically you can make it so your package, when installed, automatically enables the server extension. In conjunction with Jupyter Kernel Hook, this means your IPython extensions are automatically enabled with just a pip install!Read more about this in the officialJupyter Notebook documentation.my_package/__init__.py:(See above examples.)setup.py:fromsetuptoolsimportsetup# ...setup(# ...install_requires=[# ..."jupyter-kernel-hook"],# ...include_package_data=True,data_files=[("etc/jupyter/jupyter_notebook_config.d",["my_package_jupyter/my_package_jupyter_config.json"])],zip_safe=False# ...)my_package/my_package_jupyter_config.json:{"NotebookApp":{"nbserver_extensions":{"my_package":true}}}MANIFEST.in:include my_package/my_package_jupyter_config.jsonThe Spider-Man RuleWith great power comes great responsibility.The power to preload packages into IPython kernels is powerful and convenient at times, but it's also extremely easy to abuse.It is recommended that you be very judicious about whether your package should have this behavior.In general, merely wanting to make a package available in the global namespace is probablynota good reason to have your package preload into a kernel.  Extending the behavior of the kernel (e.g. cell magic) or packages run within it (e.g. Pandas extensions) are better reasons for having this behavior.