aiomonitor is Python 3.5+ module that adds monitor and cli capabilities for asyncio application. Idea and code borrowed from curio project. Task monitor that runs concurrently to the asyncio loop (or fast drop in replacement uvloop) in a separate thread as result monitor will work even if event loop is blocked for some reason.
Library provides an python console using aioconsole module, it is possible to execute asynchronous command inside your running application. Extensible with you own commands, in the style of the standard library's cmd module
Installation process is simple, just:
$ pip install aiomonitor
Monitor has context manager interface:
import aiomonitor
loop = asyncio.get_event_loop()
with aiomonitor.start_monitor(loop=loop):
loop.run_forever()
Now from separate terminal it is possible to connect to the application:
$ nc localhost 50101
To make arrow keys working proplerly you can use rlwrap trick:
$ rlwrap nc localhost 50101
or using included python client:
$ python -m aiomonitor.cli
Lets create simple aiohttp application, and see how aiomonitor
can integrates with it.
import asyncio
import aiomonitor
from aiohttp import web
# Simple handler that returns response after 100s
async def simple(request):
loop = request.app.loop
print('Start sleeping')
await asyncio.sleep(100, loop=loop)
return web.Response(text="Simple answer")
loop = asyncio.get_event_loop()
# create application and register route
app = web.Application(loop=loop)
app.router.add_get('/simple', simple)
# it is possible to pass dictionary with local variables
# to the python console environment
host, port = "localhost", 8090
locals_ = {"port": port, "host": host}
# init monitor just before run_app
with aiomonitor.start_monitor(loop=loop, locals=locals_):
# run application with built in aiohttp run_app function
web.run_app(app, port=port, host=host)
Lets save this code in file simple_srv.py
, so we can run it with command:
$ python simple_srv.py
======== Running on http://localhost:8090 ========
(Press CTRL+C to quit)
And now one can connect running application from separate terminal, with nc
command, immediately aiomonitor
will respond with prompt:
$ nc localhost 50101
Asyncio Monitor: 1 tasks running
Type help for commands
monitor >>>
Note in order to make arrow keys and editing working properly just prepend command with `rlwrap`:
$ rlwrap nc localhost 50101
Now you can type commands, for instance help
:
monitor >>> help
Commands:
ps : Show task table
where taskid : Show stack frames for a task
cancel taskid : Cancel an indicated task
signal signame : Send a Unix signal
stacktrace : Print a stack trace from the event loop thread
console : Switch to async Python REPL
quit : Leave the monitor
aiomonitor
supports also async python console inside running event loop so you can explore state of your application:
monitor >>> console
Python 3.5.2 (default, Oct 11 2016, 05:05:28)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
---
This console is running in an asyncio event loop.
It allows you to wait for coroutines using the 'await' syntax.
Try: await asyncio.sleep(1, result=3, loop=loop)
---
>>> await asyncio.sleep(1, result=3, loop=loop)
To leave console type exit()
:
>>> exit()
monitor >>>
aiomonitor
is very easy to extend with your own console commands.
class WebMonitor(aiomonitor.Monitor):
def do_hello(self, sin, sout, name=None):
"""Using the /hello GET interface
There is one optional argument, "name". This name argument must be
provided with proper URL excape codes, like %20 for spaces.
"""
name = '' if name is None else '/' + name
r = requests.get('http://localhost:8090/hello' + name)
sout.write(r.text + '\n')
- Python 3.5+
- aioconsole
- uvloop (optional)