Running loop idiomatically with asyncio.run() with additional tasks

I want to add my own tasks to the asyncio loop, so I’m trying to use ApplicationRunner idiomatically with asyncio.run(main()), and the main coro has

async def main() {
# all examples in the wild loop like this :frowning: 
  tasks = [asyncio.create_task(my_coro1),
  asyncio.create_task(my_coro2),
  coro # from ApplicationRunner.run with start_loop=False
 ]
 await asyncio.gather(*tasks)

But ApplicationRunner seems to create its own loop so running the coro results in “attached to a different loop” error.

In general what is the idiomatic way to add your own tasks to the event loop?

ApplicationRunner (and ApplicationRunner.run) are intended to be high-level, easy-to-use interfaces. If you need more control, you can try either passing start=False to run() (so then you are responsible for starting the event-loop) or using the newer Component API along with its .start() method (instead of e.g. autobahn.asyncio.component.run).