aboutsummaryrefslogtreecommitdiff
path: root/content/en/blog/news/20200507-python.md
blob: d4b3504221580abd354e5a662b2c38c0e2fc86fe (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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
---
date: 2020-05-07
title: "A Python API for Ouroboros"
linkTitle: "Python"
description: "Python"
author: Dimitri Staessens
---

Support for other programming languages than C/C++ has been on my todo
list for quite some time. The initial approach was using
[SWIG](http://www.swig.org), but we found the conversion always
clunky, it didn't completely work as we wanted to, and a while back we
just decided to deprecate it. Apart from C/C++ we only had a [rust
wrapper](https://github.com/chritchens/ouroboros-rs).

Until now! I finally took the time to sink my teeth into the bindings
for Python. I had some brief looks at the
[ctypes](https://docs.python.org/3/library/ctypes.html) library a
while back, but this time I looked into
[cffi](https://cffi.readthedocs.io/en/latest/) and I was amazed at how
simple it was to wrap the more difficult functions that manipulate
blocks of memory (flow\_read, but definitely the async fevent() call).
And now there is path towards a 'nice' Python API.

Here is a taste of what the
[oecho](https://ouroboros.rocks/cgit/ouroboros/tree/src/tools/oecho/oecho.c)
tool looks like in Python:

```Python
from ouroboros import *
import argparse


def client():
    f = flow_alloc("oecho")
    f.writeline("Hello, PyOuroboros!")
    print(f.readline())
    f.dealloc()


def server():
    print("Starting the server.")
    while True:
        f = flow_accept()
        print("New flow.")
        line = f.readline()
        print("Message from client is " + line)
        f.writeline(line)
        f.dealloc()


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='A simple echo client/server')
    parser.add_argument('-l', '--listen', help='run as a server', action='store_true')
    args = parser.parse_args()
    if args.listen is True:
        server()
    else:
        client()
```

I have more time in the next couple of days, so I expect this to be
released after the weekend.

Oh, and here is a picture of Ouroboros load-balancing between the C (top right)
and Python (top left) implementations using the C and Python clients:

{{<figure width="60%" src="/blog/news/20200507-python-lb.png">}}

Can't wait to get the full API done!

Cheers,

Dimitri