I often create Jupyter notebooks as plain .py files with # %% cell delimiters, like this:
# %%
import polars as pl
import numpy as np
# %%
df = pl.read_parquet('my_cool.parquet')
...
I can then run this either as a notebook using vscode-jupyter or as a script on the command line.
However, this breaks when I try to use asyncio in my notebook. Jupyter expects you to write await at the top level (with the autoawait feature), but to run as a script you need to use asyncio.run at the top level:
# %%
# this works in Jupyter, but in a script you get:
# SyntaxError: 'await' outside function
foo = await my_async_func()
# %%
# this works in a script, but in Jupyter you get:
# RuntimeError: asyncio.run() cannot be called from a running event loop
bar = asyncio.run(my_async_func)
How can I write code that works in both contexts? Some things I've tried:
nest-asyncio: this is incompatible with some other libraries I'm using
get_ipython().autoawait = Falsebefore any imports: does not fix Jupyterusing the shebang
#!/usr/bin/env -S uv run ipython: does not fix script