[00:00.000 --> 00:09.000] And it's time for our next talk. I would like you to welcome Van Duller. [00:09.000 --> 00:14.000] The stage is yours. [00:14.000 --> 00:22.000] Yes, hopefully. Oh, I can't talk. Okay. So, hello. I'm Wendy. I'm a software engineer. [00:22.000 --> 00:28.000] I work at Third Hat for six years now, and I'm part of the system in Star Team. [00:28.000 --> 00:35.000] And today, welcome on my talk about the communication with D-Bus from a Python application. [00:35.000 --> 00:40.000] So, first of all, I would like to clarify that I'm a no-way and expert on D-Bus. [00:40.000 --> 00:46.000] I'm just a very lazy programmer who wrote a library to make her job easier. [00:46.000 --> 00:51.000] So, what is D-Bus? It's a shortcut for the desktop bus. [00:51.000 --> 00:56.000] And basically, it's a system for the inter-process communication. [00:56.000 --> 01:00.000] It consists of two parts, the protocol and the bus demon. [01:00.000 --> 01:08.000] And on a typical Linux distribution, you can usually find the two bus demons, [01:08.000 --> 01:11.000] the session bus and the system bus. [01:11.000 --> 01:15.000] So, for example, this is a screenshot from my laptop. [01:15.000 --> 01:20.000] This is the visual representation of the system buses and services that you can find. [01:20.000 --> 01:26.000] And for the demonstration purposes, I've created the example chat service. [01:26.000 --> 01:33.000] And you can see on the right side that this service provides four objects, [01:33.000 --> 01:36.000] and these objects implement some interfaces. [01:36.000 --> 01:40.000] So, how do we talk to this thing from Python? [01:40.000 --> 01:43.000] We will use the D-Bus library for that. [01:43.000 --> 01:45.000] It's a library that I wrote some years ago. [01:45.000 --> 01:52.000] And basically, it's an abstraction level above bitings for the D-Bus library. [01:52.000 --> 01:56.000] Okay, so let's jump in. Let's start with the client part. [01:56.000 --> 02:01.000] So, we know that there is a D-Bus service that we want to talk to, [02:01.000 --> 02:04.000] and how do we do it from the Python application? [02:04.000 --> 02:08.000] First of all, we need to establish the connection to the message bus. [02:08.000 --> 02:13.000] In this case, we know it's the session bus, so we will use the session message bus. [02:13.000 --> 02:19.000] And the other thing that we have to create is the proxy of the remote object we want to talk to. [02:19.000 --> 02:21.000] For that, we need to know two things. [02:21.000 --> 02:25.000] The first one is the name of the D-Bus service. [02:25.000 --> 02:29.000] The second one is the object path of the remote object. [02:29.000 --> 02:33.000] After that, we can use the proxy like any other Python object, [02:33.000 --> 02:35.000] so we can get and set properties. [02:35.000 --> 02:38.000] We can call methods. [02:38.000 --> 02:44.000] And another thing we can do is to watch D-Bus signals. [02:44.000 --> 02:48.000] D-Bus signal is something you can connect to. [02:48.000 --> 02:51.000] You will create a callback, connect this callback to the signal, [02:51.000 --> 03:00.000] and every time this service emits this signal, your callback will be called and run and processed. [03:00.000 --> 03:02.000] So, this is how you do it. [03:02.000 --> 03:09.000] This service or this room proxy has one signal called the message received signal, [03:09.000 --> 03:14.000] and you can connect the callback that will just print the messages that you will receive. [03:14.000 --> 03:16.000] And that's it. [03:16.000 --> 03:21.000] This requires one more step, and that's to run an event loop. [03:21.000 --> 03:25.000] Basically, it's a little complicated to explain. [03:25.000 --> 03:32.000] It's just a black box that runs forever and handles any asynchronous events that can come up, [03:32.000 --> 03:34.000] like emitting of a signal. [03:34.000 --> 03:41.000] So, the thing runs forever unless you stop the loop or kill the application. [03:41.000 --> 03:45.000] Yeah, so, let's actually do some demonstration, [03:45.000 --> 03:52.000] because I think the demonstrations are doomed to fail, but let's try. [03:52.000 --> 03:56.000] So, here I need to start my server. [03:56.000 --> 03:58.000] Let's not dive into that yet. [03:58.000 --> 04:00.000] It's just I needed to have it running. [04:00.000 --> 04:03.000] And we can actually check the defeat. [04:03.000 --> 04:07.000] And on the session bus, you can look for my example chat, [04:07.000 --> 04:10.000] and you can see what you saw on the slides. [04:10.000 --> 04:11.000] Sorry, it's so little. [04:11.000 --> 04:14.000] And there's my room three, and there are some interfaces, [04:14.000 --> 04:17.000] and this is the interface I'm interested in. [04:17.000 --> 04:21.000] So, let's do some stuff with it. [04:21.000 --> 04:27.000] The first one, we will ask for the name of the room, [04:27.000 --> 04:28.000] and that's it. [04:28.000 --> 04:34.000] So, here I can just write the first one, [04:34.000 --> 04:39.000] and it just prints three, because we asked the room number three for the name. [04:39.000 --> 04:44.000] The second thing that we can do is to send a message to the room. [04:44.000 --> 04:47.000] So, this is the number two. [04:48.000 --> 04:51.000] This doesn't print anything, but as you can see here, [04:51.000 --> 04:56.000] the server received a message for this room, and it printed. [04:56.000 --> 05:00.000] So, if I call it several times, it prints this stuff, [05:00.000 --> 05:08.000] and if I change it to something else, [05:08.000 --> 05:13.000] I can actually talk to another object and send another message and stuff like that, [05:13.000 --> 05:18.000] and it just will send a different message to a different room. [05:18.000 --> 05:20.000] Yeah, it's a very primitive chat. [05:20.000 --> 05:24.000] Don't try to find something clever about it. [05:24.000 --> 05:29.000] And the last thing I want to show you is the signal processing. [05:29.000 --> 05:32.000] So, this is how it looks like. [05:32.000 --> 05:38.000] The callback will just print the received message with some additional stuff, [05:38.000 --> 05:42.000] and this is where I connect the callback to the signal, [05:42.000 --> 05:45.000] and then I will just start the event loop. [05:45.000 --> 05:50.000] So, for that, I actually have to... [05:50.000 --> 05:53.000] Yeah, so this thing is listening. [05:53.000 --> 05:57.000] It's waiting in the event loop, and it's waiting for any events. [05:57.000 --> 06:03.000] So, if I, again, send some messages to the... [06:03.000 --> 06:04.000] Oh, and something... [06:04.000 --> 06:06.000] Yeah, because I changed it. [06:06.000 --> 06:09.000] Yeah, that's why you shouldn't change your code. [06:12.000 --> 06:14.000] Okay, it should work now. [06:14.000 --> 06:15.000] Yes. [06:15.000 --> 06:21.000] Okay, so because it's listening on the room 3, [06:21.000 --> 06:26.000] so if I send a message to the room 3, it's well printed here, [06:26.000 --> 06:31.000] and this service behind it, it's still running, it receives the messages. [06:31.000 --> 06:33.000] So, okay. [06:33.000 --> 06:36.000] That was the client side of the things. [06:36.000 --> 06:38.000] Let's be the service. [06:38.000 --> 06:40.000] How do we do this? [06:40.000 --> 06:45.000] First of all, we need to register the debug's name of the service. [06:45.000 --> 06:50.000] That's basically you announce the name of your process, [06:50.000 --> 06:54.000] so the other applications can find you and reach you and talk to you. [06:54.000 --> 06:57.000] The other thing that you have to do is to publish some objects, [06:57.000 --> 07:02.000] so other applications can actually use some API that you provide [07:02.000 --> 07:05.000] and do some stuff with your service. [07:05.000 --> 07:08.000] And the last thing, again, is to start the event loop, [07:08.000 --> 07:11.000] and the event loop handles the incoming debug's calls, [07:11.000 --> 07:14.000] calls the relevant handlers and callbacks, [07:14.000 --> 07:18.000] and sends the return values to the callers. [07:18.000 --> 07:24.000] So, the last part that is missing is how do we create this debug's object? [07:24.000 --> 07:30.000] Every debug's object needs to provide something called the XML specification. [07:31.000 --> 07:38.000] This is a declaration of our interfaces, methods, [07:38.000 --> 07:42.000] properties and signals that this debug's object implements [07:42.000 --> 07:44.000] and that you can call. [07:44.000 --> 07:47.000] And when I saw this for the first time, [07:47.000 --> 07:51.000] I thought, oh, my God, my colleagues will do some typos in the things, [07:51.000 --> 07:53.000] and we will have so many bugs. [07:53.000 --> 07:57.000] So, the first mission I had was actually to get rid of this [07:57.000 --> 08:00.000] and make it generated automatically from the code, [08:00.000 --> 08:04.000] because I knew that we are going to do a lot of changes all the time, [08:04.000 --> 08:06.000] because it was a huge project, [08:06.000 --> 08:11.000] and in no way we would keep this same as the code. [08:11.000 --> 08:15.000] So, let's look how it can be done with the bus. [08:15.000 --> 08:20.000] All you have to do is to just use the bus interface decorator [08:20.000 --> 08:23.000] and provide the name of your interface. [08:23.000 --> 08:30.000] And this decorator just looks at the class, members of the decorated class, [08:30.000 --> 08:35.000] and for every member, it will generate this piece of the specification, [08:35.000 --> 08:39.000] and it will create this whole specification. [08:39.000 --> 08:44.000] Sometimes it collects more interfaces, it's certainly more complicated, [08:44.000 --> 08:49.000] but at the end, you don't have to do or write any XML, [08:49.000 --> 08:54.000] but you can have access to it and use it to publish your object. [08:54.000 --> 08:57.000] So, we will start with this decorator, [08:57.000 --> 09:00.000] and then you can just define a debuss method. [09:00.000 --> 09:04.000] This is definition, and at the same time the implementation of the method, [09:04.000 --> 09:07.000] so you can see it prints the message. [09:07.000 --> 09:13.000] One thing that you have to do is to provide type hints for the arguments [09:13.000 --> 09:15.000] and the return values, [09:15.000 --> 09:21.000] because debuss needs to know about the types of these of the arguments. [09:21.000 --> 09:24.000] And another thing, yeah, everything is common case. [09:24.000 --> 09:25.000] I'm sorry about that. [09:25.000 --> 09:27.000] It's just, it's a standard for debuss, [09:27.000 --> 09:31.000] and it didn't make a lot of sense to try some mapping [09:31.000 --> 09:35.000] from the traditional Python to this common case. [09:35.000 --> 09:39.000] So, it's easier to just try the common case. [09:39.000 --> 09:41.000] So, this is the method, [09:41.000 --> 09:44.000] and this is how to define a debuss property. [09:44.000 --> 09:47.000] It's just a Python property with a type hint again. [09:47.000 --> 09:50.000] And last but not least, [09:50.000 --> 09:54.000] debuss signal, you need to use a special decorator for that. [09:54.000 --> 09:57.000] And if this signal emits some additional arguments, [09:57.000 --> 10:04.000] you need to specify them as arguments of the method, kind of, yeah. [10:04.000 --> 10:06.000] This method is never called, [10:06.000 --> 10:09.000] it's just used for the definition of the signal. [10:09.000 --> 10:12.000] So, that's it. [10:12.000 --> 10:16.000] Let's have a look at the implementation of how it looks like [10:16.000 --> 10:19.000] when you, like, put it all together. [10:19.000 --> 10:22.000] So, this is the classroom. [10:22.000 --> 10:24.000] There is the decorator, [10:24.000 --> 10:27.000] and as you can see, there's just all the definitions [10:27.000 --> 10:29.000] and implementation that this class needs, [10:29.000 --> 10:33.000] and the XML is just generated by the decorator. [10:33.000 --> 10:36.000] You don't need to care about anything. [10:36.000 --> 10:39.000] The chat also has a debuss interface, [10:39.000 --> 10:42.000] but it doesn't contain anything. [10:42.000 --> 10:46.000] Here we can see later how the XML looks like, [10:46.000 --> 10:49.000] and you create a connection to the message bus, [10:49.000 --> 10:52.000] you register the name of the service, [10:52.000 --> 10:54.000] you publish some objects, [10:54.000 --> 10:57.000] and you start the event loop, and that's all. [10:57.000 --> 11:01.000] In this case, it's good to disconnect from the bus. [11:01.000 --> 11:05.000] There's an open-flow request to use the session bus [11:05.000 --> 11:08.000] as a context manager because it's nicer, [11:08.000 --> 11:10.000] but it's not merged yet, [11:10.000 --> 11:13.000] because it will register everything that you did here. [11:13.000 --> 11:16.000] So, that's a good thing to do. [11:16.000 --> 11:20.000] And here we can see that when the server was started, [11:20.000 --> 11:22.000] it printed the interfaces that were generated, [11:22.000 --> 11:25.000] so the first one is empty, there's nothing there, [11:25.000 --> 11:28.000] but with the room, it contains everything [11:28.000 --> 11:30.000] that was inside of that class. [11:30.000 --> 11:32.000] So, yeah, this was completely generated. [11:32.000 --> 11:34.000] You don't have to care about it. [11:34.000 --> 11:37.000] You don't have to figure out what type S is [11:37.000 --> 11:39.000] in this case, it's simple, [11:39.000 --> 11:42.000] but sometimes it gets a little more... [11:42.000 --> 11:44.000] Not so pretty. [11:44.000 --> 11:46.000] So, yeah, you don't have to care about it, [11:46.000 --> 11:48.000] which is, I think, great. [11:48.000 --> 11:50.000] Features. [11:50.000 --> 11:52.000] So, this bus has a lot of features [11:52.000 --> 11:54.000] because the project I was working on was big, [11:54.000 --> 11:58.000] so we wanted to do as many simplifications as we could. [11:58.000 --> 12:01.000] So, one thing that we did... [12:01.000 --> 12:03.000] Okay, I want to mention one thing. [12:03.000 --> 12:06.000] I decided I will focus on, like, the end result [12:06.000 --> 12:08.000] of these features because it's a little difficult [12:08.000 --> 12:10.000] to explain the definitions [12:10.000 --> 12:12.000] and, like, all the steps you need to do before that. [12:12.000 --> 12:15.000] So, I will just show you what you will end up with [12:15.000 --> 12:17.000] in your code. [12:17.000 --> 12:19.000] So, the first thing I want to mention is [12:19.000 --> 12:22.000] the management of the bus names and paths [12:22.000 --> 12:24.000] because you could see that there are a lot of strings [12:24.000 --> 12:26.000] you need to handle. [12:26.000 --> 12:29.000] And it's very easy to make typos in this again. [12:29.000 --> 12:32.000] So, I can... [12:32.000 --> 12:34.000] Okay, yeah. [12:34.000 --> 12:38.000] So, it's very easy to make typos in that as well. [12:38.000 --> 12:41.000] So, basically, this bus provides a system [12:41.000 --> 12:45.000] that allows you to define namespaces [12:45.000 --> 12:48.000] and objects that are published in these namespaces. [12:48.000 --> 12:52.000] And at the end, you will have these very simple objects [12:52.000 --> 12:54.000] called chat and Room 3, [12:54.000 --> 12:58.000] and you can just use these objects to create proxies [12:58.000 --> 13:00.000] or ask for the interface name [13:00.000 --> 13:03.000] or ask for the service name or get the object pass. [13:03.000 --> 13:06.000] And you don't have to care about the strings behind it [13:06.000 --> 13:10.000] because they are created from what you defined earlier. [13:10.000 --> 13:15.000] Yeah, I can get to that later if you have time. [13:15.000 --> 13:20.000] So, another thing that Das Bus provides, [13:20.000 --> 13:25.000] it's management of a group of publishable objects. [13:25.000 --> 13:29.000] So, let's say that the chat is not static. [13:29.000 --> 13:31.000] It doesn't have only streams, [13:31.000 --> 13:34.000] you can ask the chat to create a new room [13:34.000 --> 13:37.000] and you want to get the bus pass of that room [13:37.000 --> 13:39.000] so you can connect to it. [13:39.000 --> 13:43.000] So, yeah, you can implement it manually on your own [13:43.000 --> 13:45.000] and make sure that every room has a unique pass. [13:45.000 --> 13:48.000] And if someone wants to do something with that room, [13:48.000 --> 13:52.000] you can just figure out again what was the room [13:52.000 --> 13:55.000] or you can just use the room container. [13:55.000 --> 13:56.000] It's very easy. [13:56.000 --> 13:59.000] You just provide the namespace that the container can use [13:59.000 --> 14:02.000] and you will specify the message bus [14:02.000 --> 14:05.000] that can be used to publish these objects. [14:05.000 --> 14:08.000] And the whole purpose of this container [14:08.000 --> 14:13.000] is just to give it a Python object and get a D-Bus pass. [14:13.000 --> 14:16.000] And it works the same way backwards. [14:16.000 --> 14:19.000] So, if you receive an object pass, you can get a room. [14:19.000 --> 14:22.000] So, with this mapping, [14:22.000 --> 14:26.000] you can, like, deal with this mapping very early [14:26.000 --> 14:29.000] and in your code, you only have the objects. [14:29.000 --> 14:33.000] You don't have to care about the D-Bus implementation behind it. [14:33.000 --> 14:37.000] So, yeah, it's a little difficult to explain, [14:37.000 --> 14:43.000] but it can simplify your life a lot. [14:43.000 --> 14:45.000] Yeah, another thing I want to talk about [14:45.000 --> 14:47.000] is how to handle D-Bus errors. [14:47.000 --> 14:52.000] So, this bus raises a default exception by default, [14:52.000 --> 14:55.000] but sometimes you want to handle a specific D-Bus error [14:55.000 --> 14:59.000] or maybe you want to raise a specific D-Bus error [14:59.000 --> 15:01.000] from your service. [15:01.000 --> 15:03.000] It's a very easy thing to do. [15:03.000 --> 15:05.000] There's a special decorator for that [15:05.000 --> 15:07.000] that you can use for your exceptions. [15:07.000 --> 15:11.000] And in the decorator, you specify the D-Bus name of this error. [15:11.000 --> 15:14.000] And that's all you have to do to be able to use this exception [15:14.000 --> 15:15.000] in your code. [15:15.000 --> 15:20.000] So, once you decorate it, you can raise it in a service [15:20.000 --> 15:22.000] and you can accept it in the client, [15:22.000 --> 15:26.000] and you don't have to care about the magic between that. [15:26.000 --> 15:29.000] Yeah, that's also a cool thing to do. [15:29.000 --> 15:31.000] D-Bus structures. [15:31.000 --> 15:33.000] So, this is very... [15:33.000 --> 15:36.000] Yeah, this is a funny thing. [15:36.000 --> 15:39.000] D-Bus doesn't have native support for structures. [15:39.000 --> 15:43.000] So, what everyone does is they send dictionaries [15:43.000 --> 15:46.000] that map attribute names to attribute values. [15:46.000 --> 15:49.000] And since these values can be of different types, [15:49.000 --> 15:53.000] you have to wrap them inside variants. [15:53.000 --> 15:55.000] Variant is a special data type [15:55.000 --> 15:59.000] that basically couples the data and the type together. [15:59.000 --> 16:03.000] So, when you send it from your service, [16:03.000 --> 16:06.000] the client is able to interpret the data [16:06.000 --> 16:11.000] even though it didn't know the type of this data before. [16:11.000 --> 16:15.000] So, this is a pretty horrible thing to work with, [16:15.000 --> 16:19.000] especially when you need to receive the structure, [16:19.000 --> 16:21.000] change something, and send it somewhere else. [16:21.000 --> 16:24.000] Because creating these variants is not easy, [16:24.000 --> 16:26.000] variants are not changeable, [16:26.000 --> 16:28.000] so you have to always create new ones, [16:28.000 --> 16:30.000] and yeah, it's not pretty. [16:30.000 --> 16:33.000] So, with D-Bus, you can actually describe the structure [16:33.000 --> 16:35.000] using data classes, [16:35.000 --> 16:38.000] and these classes just have some properties. [16:38.000 --> 16:40.000] And there's a lot of automation [16:40.000 --> 16:43.000] that allows you to basically give it the dictionary. [16:43.000 --> 16:46.000] It will transform the dictionary into a Python object, [16:46.000 --> 16:48.000] then you can just play with the Python object, [16:48.000 --> 16:50.000] and when you need the structure again, [16:50.000 --> 16:53.000] you will just go to structure [16:53.000 --> 16:57.000] to get the structure that you can send on D-Bus. [16:57.000 --> 17:01.000] Yeah, so that's another thing you can do. [17:01.000 --> 17:03.000] Lastly, this is a new feature [17:03.000 --> 17:07.000] that I was working on with some people last year. [17:07.000 --> 17:10.000] Yeah, I would like to think this way. [17:10.000 --> 17:14.000] I would like to use this to thank everyone who was involved in this, [17:14.000 --> 17:17.000] because it was a bigger issue than I expected. [17:17.000 --> 17:24.000] And basically, you can send Unix file descriptors through D-Bus. [17:24.000 --> 17:28.000] It works only on Unix systems, obviously, [17:28.000 --> 17:31.000] and its optional feature is disabled by default [17:31.000 --> 17:33.000] because there's some overhead, [17:33.000 --> 17:38.000] and I didn't want it to slow down everyone's services. [17:38.000 --> 17:41.000] So all you have to do is when you create the proxy, [17:41.000 --> 17:44.000] you will specify a little different client library [17:44.000 --> 17:47.000] or the server library that will be used [17:47.000 --> 17:53.000] to process the incoming calls or the requests, [17:53.000 --> 17:58.000] and it basically means that if... [17:58.000 --> 18:00.000] Yeah, it's a little complicated [18:00.000 --> 18:04.000] because D-Bus has a special support for Unix file descriptors, [18:04.000 --> 18:08.000] but it's very messy when you have to deal with it specifically, [18:08.000 --> 18:11.000] and with this extension, you don't have to care about it. [18:11.000 --> 18:14.000] Basically, if you want to send a file descriptor, [18:14.000 --> 18:16.000] you will just send a file descriptor [18:16.000 --> 18:20.000] and receive a file descriptor on the other side. [18:20.000 --> 18:26.000] Yeah, so these features can be very hard to understand, [18:26.000 --> 18:28.000] and I get it. [18:28.000 --> 18:30.000] So I want to mention that this is optional. [18:30.000 --> 18:33.000] It's not something that you have to use if you want to use D-Bus, [18:33.000 --> 18:37.000] and I would suggest if you don't have the needs to use them, [18:37.000 --> 18:42.000] don't use them, keep it simple, do whatever is the easiest, [18:42.000 --> 18:46.000] because there can be a lot of additional code [18:46.000 --> 18:50.000] that can be hard to understand. [18:50.000 --> 18:54.000] Another thing I want to mention is that I acknowledge [18:54.000 --> 18:56.000] that every project is a little different [18:56.000 --> 18:58.000] and has very different needs, [18:58.000 --> 19:02.000] and sometimes you can make a lot of assumptions about your service, [19:02.000 --> 19:07.000] but you might not need half of the D-Bus support that there is, [19:07.000 --> 19:10.000] so you can simplify some stuff a lot, [19:10.000 --> 19:13.000] and that's great, but that's often not generic enough [19:13.000 --> 19:16.000] to be implemented in a library like D-Bus. [19:16.000 --> 19:21.000] So what you can do, actually, is to take any piece of D-Bus, [19:21.000 --> 19:24.000] very implemented, to fit it to your needs, [19:24.000 --> 19:27.000] and propagate it in the right places, [19:27.000 --> 19:31.000] so D-Bus will use it instead of the original implementation. [19:31.000 --> 19:35.000] I want to mention this because we were in this position [19:35.000 --> 19:37.000] at the beginning of our project, [19:37.000 --> 19:42.000] and we had a lot of troubles with the library that we used back then, [19:42.000 --> 19:45.000] and basically we had to patch the whole library [19:45.000 --> 19:49.000] because we were not able to get the stuff that we needed, [19:49.000 --> 19:56.000] and it wasn't easy to just change it, so we had to patch it. [19:56.000 --> 20:00.000] So this is the link to the library. [20:00.000 --> 20:04.000] There's an open discussion session, there's issue tracker, [20:04.000 --> 20:08.000] so if you have any suggestions, questions, you can find me there, [20:08.000 --> 20:11.000] reach me there, I don't hesitate to ask. [20:11.000 --> 20:14.000] There are some examples. [20:14.000 --> 20:20.000] You should be able to find there examples that are similar to the one that I showed you. [20:20.000 --> 20:25.000] I think I will post there also the demo stuff [20:25.000 --> 20:29.000] because it's easier to understand. [20:30.000 --> 20:34.000] There's also documentation that might help you [20:34.000 --> 20:38.000] because maybe this talk didn't help you so much. [20:38.000 --> 20:42.000] So that's all from me, thank you so much for coming. [20:42.000 --> 20:45.000] Does anyone have any questions? [20:46.000 --> 20:53.000] APPLAUSE [21:01.000 --> 21:05.000] Hi, I just wanted to ask, where do you find people are using this? [21:05.000 --> 21:07.000] Is it in chat message applications, [21:07.000 --> 21:11.000] or what are the applications of this for most people? [21:12.000 --> 21:16.000] What are the applications for providing the D-Bus API that you can... [21:16.000 --> 21:20.000] Okay, so on the next system, it's basically... [21:23.000 --> 21:26.000] Any... like there are printers, [21:26.000 --> 21:29.000] or you can control the media player, [21:29.000 --> 21:34.000] or you can set up your firewall, or on the session bus. [21:34.000 --> 21:38.000] I think this chat actually has their own D-Bus API. [21:38.000 --> 21:42.000] So it's more like the applications that are running on your desktop [21:42.000 --> 21:44.000] often provide this D-Bus API, [21:44.000 --> 21:47.000] so you can write some scripts to tweak them and to control them. [21:47.000 --> 21:50.000] So, yeah, that's it. [21:54.000 --> 22:04.000] Does D-Bus support properties and annotations? [22:05.000 --> 22:08.000] Properties, yes, annotations. [22:10.000 --> 22:14.000] Do you mean like properties changed annotations, or stuff like that? [22:14.000 --> 22:18.000] Like emits changed signals and deprecated and stuff like that. [22:21.000 --> 22:23.000] I'm not sure about it. [22:23.000 --> 22:27.000] I think it's not like needed, it's just like a recommendation for the documentation, [22:27.000 --> 22:30.000] but it's not something that... [22:30.000 --> 22:34.000] Otherwise, the client can't see that the server may support an API call, [22:34.000 --> 22:38.000] but it's marked as deprecated. [22:38.000 --> 22:43.000] Okay, yeah, I think it doesn't support custom annotations, [22:43.000 --> 22:46.000] but that's definitely something I can look at if it's like... [22:46.000 --> 22:49.000] Just wanted if you can add them, that's fine. [22:49.000 --> 22:51.000] Yeah, yeah, so I don't think that this is supported, [22:51.000 --> 22:54.000] but it's definitely supportable. [23:01.000 --> 23:07.000] Hi, why would someone want to use D-Bus... [23:07.000 --> 23:14.000] I mean, Daspus versus some other D-Bus library that's out there for Python? [23:14.000 --> 23:18.000] Yeah, okay, so this library was actually inspired by PyD-Bus, [23:18.000 --> 23:20.000] which is also very popular. [23:20.000 --> 23:23.000] It's just we hit some issues, [23:23.000 --> 23:26.000] and it's complicated, like you need to think a lot for us. [23:26.000 --> 23:30.000] So at some point, I just got so frustrated, [23:30.000 --> 23:32.000] I decided to rewrite it and create Daspus, [23:32.000 --> 23:35.000] but yeah, there are a lot of interesting libraries, [23:35.000 --> 23:37.000] and sometimes they are a little simpler, [23:37.000 --> 23:42.000] and it might be enough, so you don't have to use this one. [23:42.000 --> 23:48.000] This is much easier if you... [23:48.000 --> 23:50.000] If you have a lot of D-Bus API, [23:50.000 --> 23:55.000] because with our project, there are several D-Bus services, [23:55.000 --> 23:58.000] and it has a lot of objects, a lot of interfaces, [23:58.000 --> 24:00.000] and it would be very difficult to deal with it [24:00.000 --> 24:04.000] with a library that operates on a lower level. [24:04.000 --> 24:08.000] So we needed a lot of abstraction to make sure that the code is okay. [24:11.000 --> 24:13.000] We have time for one last question. [24:19.000 --> 24:21.000] Who was first? Maybe two questions. [24:22.000 --> 24:25.000] Hello. Thank you for the library. [24:25.000 --> 24:27.000] I've been trying it and it's great. [24:27.000 --> 24:31.000] I wanted to ask a question regarding the event loop. [24:31.000 --> 24:35.000] Lately, I've been doing some work with D-Bus, [24:35.000 --> 24:39.000] and I find it very painful that most libraries [24:39.000 --> 24:43.000] rely on the G-Leap main loop, [24:43.000 --> 24:49.000] rather than the default event loop coming from AsyncIO. [24:49.000 --> 24:54.000] I saw that in the code base, there is an abstract event loop [24:54.000 --> 24:57.000] that could become something else, [24:57.000 --> 24:59.000] but do you have any plans about that? [24:59.000 --> 25:03.000] Yeah, so right now, I don't know about the demand [25:03.000 --> 25:07.000] for additional support for other event loops, like backends, [25:07.000 --> 25:11.000] but the code is implemented in a way that it should be possible to do it. [25:11.000 --> 25:14.000] So if there is enough people who would be interested in this, [25:14.000 --> 25:16.000] that's definitely something I would like to look at. [25:16.000 --> 25:20.000] It's just, yeah, it's no demand right now. [25:23.000 --> 25:25.000] Thanks a lot. Thank you again. [25:33.000 --> 25:37.000] You probably have a great audience for people interested in Linux desktop here. [25:46.000 --> 25:48.000] Thank you.