2025, Dec 30 19:00

How to Run Your Script and Drop Into the Python asyncio REPL: the PYTHONSTARTUP Solution

Learn how to run your script first and then open the Python asyncio REPL with python -m asyncio using PYTHONSTARTUP to preload state, plus exec fallback.

Bootstrapping an async session is a common need: you want to run a file, set up some objects, and then drop straight into the asyncio REPL to “play” with the results. Running python -m asyncio gives you the interactive event-loop–aware shell, while python -i ./script.py executes a file and stays interactive. The question is how to combine both without extra steps.

Problem statement

The straightforward flags don’t compose. Reordering options and even using the end-of-options marker -- doesn’t achieve “run my file, then launch the asyncio REPL”.

python -m asyncio
python -i ./boot.py
python -m asyncio -i ./boot.py
python -i ./boot.py -m asyncio
python -m asyncio -- -i ./boot.py

Another workaround is to evaluate a file from within the shell. That does work, but adds manual steps:

exec(open("preload_async.py").read())

Why it happens

The asyncio entry point invoked by python -m asyncio starts its own interactive mode. It’s not designed to chain with -i so that your file runs first and the asyncio-aware REPL opens second. Simply rearranging flags won’t change that.

The reliable way: PYTHONSTARTUP

Use the environment variable PYTHONSTARTUP to run code before interactive mode starts. It can be used to load modules or execute any setup you want at the moment the REPL is created. When configured at the system level, it is always loaded before interactive mode; no extra commands are needed.

On Linux you can set it inline for a one-off session and still launch the asyncio REPL:

PYTHONSTARTUP=boot.py python -m asyncio

The asyncio entry point honors this variable. In its logic, it checks for PYTHONSTARTUP and evaluates it before dropping into the interactive loop. Conceptually, the check looks like this:

if init_path := os.getenv("PYTHONSTARTUP"):
    ...  # load and execute startup file before entering the REPL

This achieves exactly the desired workflow: your boot.py runs first, then you land in the asyncio REPL with the results ready to use—no additional typing.

Alternative within the shell

If setting PYTHONSTARTUP isn’t an option, evaluating a file from the REPL itself remains a practical fallback:

exec(open("preload_async.py").read())

This is simple and effective, just not as streamlined as the environment-variable approach.

Why this matters

The goal is to immediately “play” in the async REPL with the state produced by your script, and to provide the simplest possible procedure for other people to follow. Using PYTHONSTARTUP means they run one command and arrive in a ready-to-use async shell without additional steps.

Wrap-up

If you need to execute a file and then enter the asyncio REPL, set PYTHONSTARTUP to your bootstrap file and start the session with python -m asyncio. If inline configuration is convenient, on Linux you can do it in a single command. If that’s not feasible, loading the file inside the shell with exec(open(...).read()) still gets the job done. If you want to inspect how the asyncio shell is wired, you can locate the asyncio package and see that its __main__.py checks PYTHONSTARTUP; you can also use this code to create own version. The minimal, repeatable path for others remains the environment-variable approach, which avoids extra commands and delivers an immediate async playground.