summaryrefslogtreecommitdiffstats
path: root/examples/asyncio-python-embed.py
blob: a8fbba5a90ead6bd41253407853fc5687577c67e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/env python
"""
(Python >3.3)

This is an example of how we can embed a Python REPL into an asyncio
application. In this example, we have one coroutine that runs in the
background, prints some output and alters a global state. The REPL, which runs
inside another coroutine can access and change this global state, interacting
with the running asyncio application.
The ``patch_stdout`` option makes sure that when another coroutine is writing
to stdout, it won't break the input line, but instead writes nicely above the
prompt.
"""
import asyncio

from ptpython.repl import embed

loop = asyncio.get_event_loop()
counter = [0]


async def print_counter() -> None:
    """
    Coroutine that prints counters and saves it in a global variable.
    """
    while True:
        print("Counter: %i" % counter[0])
        counter[0] += 1
        await asyncio.sleep(3)


async def interactive_shell() -> None:
    """
    Coroutine that starts a Python REPL from which we can access the global
    counter variable.
    """
    print(
        'You should be able to read and update the "counter[0]" variable from this shell.'
    )
    try:
        await embed(globals=globals(), return_asyncio_coroutine=True, patch_stdout=True)
    except EOFError:
        # Stop the loop when quitting the repl. (Ctrl-D press.)
        loop.stop()


async def main() -> None:
    asyncio.create_task(print_counter())
    await interactive_shell()


if __name__ == "__main__":
    asyncio.run(main())