Skip to main content Link Menu Expand (external link) Document Search Copy Copied

You can create tasks using the server[‘loop’]. Consider the following example:

import asyncio

from tremolo import Tremolo

app = Tremolo()

async def my_coro(fut):
    await asyncio.sleep(10)
    fut.set_result(b'Promised result after sleep 10s')

@app.route('/hello')
async def hello_world(**server):
    tasks = server['context'].tasks
    loop = server['loop']

    fut = loop.create_future()

    tasks.append(
        loop.create_task(my_coro(fut))
    )

    yield b'Processing... '

    await fut # wait promise done

    yield fut.result()

if __name__ == '__main__':
    app.run('0.0.0.0', 8000, debug=True)

The code above runs an awaitable my_coro using loop.create_task(). So that it does not wait for my_coro in the main task, not blocking the following yield b'Processing... to be executed.

Appending tasks to server['context'].tasks is not required. But it will help Tremolo to cancel pending tasks on client disconnect.

For convenience, you can use the ServerTasks.create. Just add tasks=None placeholder parameter in the handler to use it:

@app.route('/hello')
async def hello_world(tasks=None, **server):
    # ...

    task = tasks.create(my_coro(fut))

Contexts

server['context'] is a mutable object (think a dict with a dot notation, or a SimpleNamespace).

It can be used to share state or data e.g. between middleware and handler, in a lifetime of a request.

ctx = server['context']
# or
# ctx = server['request'].context

ctx.anykey = 'mydata'

Note that the following attributes are reserved: options, and tasks.