Skip to main content

Python asynchronous I/O package for LDMud

Project description

Python asynchronous I/O package for LDMud

This is a python module that enables the use of the Python asyncio module with LDMud 3.6.2 and later. The module doesn't export any names, it just extends the Python asyncio module to work with LDMud.

Usage

Install from the python package index

The efun package can be downloaded from the python package index:

pip3 install --user ldmud-asyncio

Build & install the package yourself

You can build the package yourself.

First clone the repository

git clone https://github.com/ldmud/python-asyncio.git

Install the package

cd python-asyncio
python3 setup.py install --user

Automatically load the module at startup

In your Python startup script for LDMud add the following line:

import ldmud_asyncio

Examples

call_out() replacement

import ldmud, ldmud_asyncio, asyncio

async def do_call_out(cb, sec):
    await asyncio.sleep(sec)
    cb()

def efun_call_out(cb: ldmud.Closure, sec: int) -> None:
    asyncio.run(do_call_out(cb, sec))

ldmud.register_efun("py_call_out", efun_call_out)

Call a program and return the lines

import ldmud, ldmud_asyncio, asyncio

async def do_exec(prog, cb):
    proc = await asyncio.create_subprocess_exec(prog, stdout=asyncio.subprocess.PIPE)

    async for line in proc.stdout:
        cb(line.decode())

    await proc.wait()
    cb(0)

def efun_exec(prog: str, cb: ldmud.Closure) -> None:
    asyncio.run(do_exec(prog, cb))

ldmud.register_efun("py_exec", efun_exec)

Start a websockets server

This is the synchronization example from the websockets package. Here we only added an efun to influence the value as well.

This is the Python code:

import ldmud, ldmud_asyncio, asyncio, websockets, json

STATE = {"value": 0}
USERS = set()

def state_event():
    return json.dumps({"type": "state", **STATE})

def users_event():
    return json.dumps({"type": "users", "count": len(USERS)})

async def notify_state():
    if USERS:  # asyncio.wait doesn't accept an empty list
        message = state_event()
        await asyncio.wait([user.send(message) for user in USERS])

async def notify_users():
    if USERS:  # asyncio.wait doesn't accept an empty list
        message = users_event()
        await asyncio.wait([user.send(message) for user in USERS])

async def register(websocket):
    USERS.add(websocket)
    await notify_users()

async def unregister(websocket):
    USERS.remove(websocket)
    await notify_users()

async def counter(websocket, path):
    # register(websocket) sends user_event() to websocket
    await register(websocket)
    try:
        await websocket.send(state_event())
        async for message in websocket:
            data = json.loads(message)
            if data["action"] == "minus":
                STATE["value"] -= 1
                await notify_state()
            elif data["action"] == "plus":
                STATE["value"] += 1
                await notify_state()
    finally:
        await unregister(websocket)

asyncio.run(websockets.serve(counter, "localhost", 6789))

async def do_ws_set_value(val):
    STATE["value"] = val
    await notify_state()

def efun_ws_set_value(val: int) -> None:
    asyncio.run(do_ws_set_value(val))

ldmud.register_efun("py_ws_set_value", efun_ws_set_value)

And here the HTML code to run in the browser:

<!DOCTYPE html>
<html>
    <head>
        <title>WebSocket demo</title>
        <style type="text/css">
            body {
                font-family: "Courier New", sans-serif;
                text-align: center;
            }
            .buttons {
                font-size: 4em;
                display: flex;
                justify-content: center;
            }
            .button, .value {
                line-height: 1;
                padding: 2rem;
                margin: 2rem;
                border: medium solid;
                min-height: 1em;
                min-width: 1em;
            }
            .button {
                cursor: pointer;
                user-select: none;
            }
            .minus {
                color: red;
            }
            .plus {
                color: green;
            }
            .value {
                min-width: 2em;
            }
            .state {
                font-size: 2em;
            }
        </style>
    </head>
    <body>
        <div class="buttons">
            <div class="minus button">-</div>
            <div class="value">?</div>
            <div class="plus button">+</div>
        </div>
        <div class="state">
            <span class="users">?</span> online
        </div>
        <script>
            var minus = document.querySelector('.minus'),
                plus = document.querySelector('.plus'),
                value = document.querySelector('.value'),
                users = document.querySelector('.users'),
                websocket = new WebSocket("ws://127.0.0.1:6789/");
            minus.onclick = function (event) {
                websocket.send(JSON.stringify({action: 'minus'}));
            }
            plus.onclick = function (event) {
                websocket.send(JSON.stringify({action: 'plus'}));
            }
            websocket.onmessage = function (event) {
                data = JSON.parse(event.data);
                switch (data.type) {
                    case 'state':
                        value.textContent = data.value;
                        break;
                    case 'users':
                        users.textContent = (
                            data.count.toString() + " user" +
                            (data.count == 1 ? "" : "s"));
                        break;
                    default:
                        console.error(
                            "unsupported event", data);
                }
            };
        </script>
    </body>
</html>

Have fun!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ldmud-asyncio-0.0.4.tar.gz (6.4 kB view details)

Uploaded Source

Built Distribution

ldmud_asyncio-0.0.4-py3-none-any.whl (6.5 kB view details)

Uploaded Python 3

File details

Details for the file ldmud-asyncio-0.0.4.tar.gz.

File metadata

  • Download URL: ldmud-asyncio-0.0.4.tar.gz
  • Upload date:
  • Size: 6.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.4.2 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.57.0 CPython/3.9.2

File hashes

Hashes for ldmud-asyncio-0.0.4.tar.gz
Algorithm Hash digest
SHA256 db64f9be44217a6c49448a57ca845db26cf6e90267476e01751bac39599d25bc
MD5 b80f682b701273fb1c51c6e3fce5ee80
BLAKE2b-256 e856fc7fbfcb270407383c040a15cb3fbde3f4e2417ca8458b45d88bdabe74be

See more details on using hashes here.

File details

Details for the file ldmud_asyncio-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: ldmud_asyncio-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 6.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.4.2 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.57.0 CPython/3.9.2

File hashes

Hashes for ldmud_asyncio-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 d08bfc9298639a7ffd4dcc7ab448662c0c6d35965d638e6e2cce8d7955c9ad63
MD5 e5f6d828655d6eb212d9af0234da60a3
BLAKE2b-256 4e4183a4160f76f66dbd5825735eb0cd4fefa13c521336555772e4975df5caba

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page