Is it possible to run only a single step of the asyncio event loop

The missing of public method like loop.run_once() is intentional. Not every supported event loop has a method to iterate one step. Often underlying API has methods for creating event loop and running it forever but emulating single step may be very ineffective.

If you really need it you may implement single-step iteration easy:

import asyncio


def run_once(loop):
    loop.call_soon(loop.stop)
    loop.run_forever()


loop = asyncio.get_event_loop()

for i in range(100):
    print('Iteration', i)
    run_once(loop)

Take a look at this example.

import asyncio
from tkinter import *

class asyncTk(Tk):
    def __init__(self):
        super().__init__()
        self.running = True
        self.protocol("WM_DELETE_WINDOW", self.on_closing)

    def on_closing(self):
        self.running = False
        self.destroy()
        
    def __await__(self):
        while self.running:
            self.update()
            yield

async def asd():
    for x in range(1,10):
        await asyncio.sleep(1)
        print(x)

async def main():
    w = asyncTk()
    asyncio.create_task(asd())
    await w

asyncio.run(main())