Creating a Service#

Standard Service Structure#

There is the standard service directory structure.

SERVICE_NAME/
├── __init__.py
├── _imports.py
├── service.py
├── constants.py
├── util.py
├── related_class.py
└── related_class2.py

_imports.py#

If the service requires additional imports from gi.repository, which, in turn, requires installing dependencies by an user, define them here.

It should look like this:

import gi
import sys
from ignis.exceptions import GvcNotFoundError

# Gvc is here just for example.
try:
    if "sphinx" not in sys.modules:  # prevent possible errors while building docs
        gi.require_version("Gvc", "1.0")
    from gi.repository import Gvc  # type: ignore
except (ImportError, ValueError):
    raise GvcNotFoundError() from None

__all__ = ["Gvc"]

And then, import them ONLY from this file:

from ._imports import Gvc
# ... rest of code

service.py#

Place the service class itself in this file.

All services should inherit from the BaseService class.

Here is simple template for service.

from ignis.base_service import BaseService

class ExampleService(BaseService):
    def __init__(self):
        super().__init__()
        # do other stuff here

constants.py#

Define here constants for the service (if they are).

SOME_CONSTANT = 1
ANOTHER_CONSTANT = "30"

util.py#

If the service have additional non-class functions/utilities, define them here.

def useful_func(x: int, y: int) -> int:
    # ... do something
    return x + y

__init__.py#

Don't forget to add the service class, related classes and constants to the __all__ list here.

from .service import ExampleService
from .related_class import RelatedClass1
from .related_class2 import RelatedClass2
from .constants import SOME_CONSTANT

__all__ = [
    "ExampleService",
    "RelatedClass1",
    "RelatedClass2",
    "SOME_CONSTANT"
]

Creating D-Bus Service#

We will use DBusService in this template.

  • Use PascalCase for D-Bus methods and properties naming.

  • Also make D-Bus methods/properties private (add __ before name).

from gi.repository import Gio, GLib
from ignis.base_service import BaseService
from ignis.dbus import DBusService

class ExampleService(BaseService):
    def __init__(self):
        super().__init__()
        self.__dbus = DBusService(...)
        self.__dbus.register_dbus_method("MyMethod", self.__MyMethod)
        self.__dbus.register_dbus_property("MyProperty", self.__MyProperty)

    def __MyMethod(self, invocation: Gio.DBusMethodInvocation, param1: str, param2: int, *args) -> GLib.Variant:
        print("do something")
        return GLib.Variant("(is)", (42, "Hello world!"))

    def __MyProperty(self) -> GLib.Variant:
        return GLib.Variant("(b)", (False,))