Skip to content

REPL examples

Before starting. You know python already have an asyncio REPL:

python -m asyncio
asyncio REPL 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> |

Is it OK? It's a little buggy. Try to press Ctrl+C to send KeyboardInterrupt. Does it handles correctly? Then press Tab. When you have readline library it should complete the command line, but it does not work too

There are some tries to fix this anoying behavior. Right now the best solution is PTRepl Extension -- it works fine on Linux, MacOS and Windows

Vanila asyncio repl ReplUnit. Implement the unit

This solution does not requires external libraries and uses ctypes. On Linux and MacOS when library readline is available, this solution is good enough, but on Windows it's the same awful as built-in asyncio REPL. My other variants are drop-in replacements of ReplUnit and everything you read here is relevant for other implementations

Start from creating file, for example, my_repl.py:

from systempy import Unit, ReplUnit


class MyReplUnit(ReplUnit, Unit):
    """
    Just add your component mixins. For example, initialize models and other
    components. Also you may add your custom variables into repl globals.
    It's useful to pre-import some modules, like models or tasks
    """

    repl_variables = {
        "my_variable": "my_value",
    }


unit = MyReplUnit()


if __name__ == '__main__':
    unit.run_sync()

Run the REPL

Now you are able to use this REPL:

python -m my_repl

PrettyReplUnit Extension

This is a subclass of ReplUnit but having a little bit changed banner:

(venv) kai@asus-ux360c:~/Projects/my-pet-project$ python -m petproject.mymodule.repl
asyncio REPL 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.

Working on petproject.mymodule.repl
Variables: ['asyncio', 'config', 'models', 'othermodule_service', 'singleton', 'tasks', 'unit', 'views']
>>> |

API reference is the same, and problems are the same too. This is my pet project code with minimal changes

from systempy import Unit
from systempy.ext.celery import CeleryUnit
from systempy.ext.starlette import StarletteUnit
from systempy.ext.pretty_repl import PrettyReplUnit

from petproject.common.systempy import (
    ConfigUnit,
    LoggerUnit,
    LoggingUnit,
    SQLAlchemyMariaDBUnit,
    MyFirstDatabaseUnit,
)

from . import config
from . import singleton
from . import views

from petproject.common import models
from petproject.common.service import othermodule as othermodule_service
from petproject.othermodule import tasks


class MyPrettyReplUnit(
    ConfigUnit,
    LoggerUnit,
    LoggingUnit,
    CeleryUnit,
    StarletteUnit,
    SQLAlchemyMariaDBUnit,
    MyFirstDatabaseUnit,
    PrettyReplUnit,
    Unit,
):
    repl_variables = {
        "views": views,
        "singleton": singleton,
        "config": config,
        "models": models,
        "othermodule_service": othermodule_service,
        "tasks": tasks,
    }


unit = MyPrettyReplUnit(
    config=config.config,
)


if __name__ == '__main__':
    unit.run_sync()

PTRepl Extension

This is drop-in replacement of PrettyReplUnit Extension, but it implemented in absolutelly different way and relies on ptpython library. It works fine on Linux, MacOS and Windows, and I like it's hints and syntax highliting. Before starting you have to install this requirement:

pip install ptpython

Finally you can change the PrettyReplUnit Extension and replace import statement:

from systempy.ext.starlette import StarletteUnit
# from systempy.ext.pretty_repl import PrettyReplUnit
from systempy.ext.ptrepl import PTRepl as PrettyReplUnit

If you like this REPL implementation, you may remove old import and refactor your code