i3pyblocks.blocks.base

i3pyblocks block.

This module includes implementation for the Block class, used to represent a i3bar block. It also includes some more advanced implementations of Block class, like PollingBlock.

Module Contents

Classes

Block

Base Block.

PollingBlock

Polling Block.

SyncBlock

Sync Block.

PollingSyncBlock

Polling sync Block.

class i3pyblocks.blocks.base.Block(*, block_name: Optional[str] = None, default_state: Optional[i3pyblocks._internal.models.State] = None, ignore_errors: bool = False)

Base Block.

A Block represents each part that composes an i3pyblocks output. It is responsible extracting, parsing and processing the information, and also formatting so it can be output in i3bar later.

This is an abstract class defining the interface for what a Block is. It should not be used directly, instead it should be derivated and its abstract methods should be implemented.

Parameters
  • block_name – Allows you to set a custom internal representation for the class. This should only be useful if you need to differentiate between multiple instances of the same module in a consistent way (i.e.: you can’t rely on something random like the id). If not passed this will use by default the string representation of the class name.

  • default_state

    Defines the default state of the Block, that is, the value that will be shown unless the state is updated by update_state() method. For example, let’s say you want a block that has a permanent green background (unless overriden), so you can do something like:

    block_instance = Block(
        default_state={
            "background": "#008000",
        },
    )
    

    And all calls to result() will have background == "#008000", unless overriden by update_state() with a different value.

  • ignore_errors – If set to true, do not show errors in the bar for this block. May be useful in cases where the block is expected to fail in some situations. The errors will still be logged.

Variables
  • id – Unique identifier for Block based on UUIDv4.

  • ex_format

    Reference of ExtendedFormatter’s format() method available to all children. Supports some additional funcionality compared to the default str().format() method, for example:

    s = "HellO WorlD!"
    print(self.ex_format("{!u}", s))  # "HELLO WORLD!"
    print(self.ex_format("{!l}", s))  # "hello world!"
    print(self.ex_format("{!c}", s))  # "Hello world!"
    print(self.ex_format("{!t}", s))  # "Hello World!"
    

See also

For details about each of the keys available in default_state parameter, see update_state() documentation.

ex_format :Callable[Ellipsis, str]
update_state(self, full_text: Optional[str] = '', short_text: Optional[str] = None, color: Optional[str] = None, background: Optional[str] = None, border: Optional[str] = None, border_top: Optional[int] = None, border_right: Optional[int] = None, border_bottom: Optional[int] = None, border_left: Optional[int] = None, min_width: Optional[int] = None, align: Optional[str] = None, urgent: Optional[bool] = None, separator: Optional[bool] = None, separator_block_width: Optional[int] = None, markup: Optional[str] = None) None

Updates Block’s state.

The state is what will be shown by the Block in the next update, unless another update occurs before a Block’s push_update() method is called.

Each of this method arguments is from blocks in i3bar protocol, since they’re mapped directly from it (so a full_text="foo" results in a {"full_text": "foo"} in the Block’s output).

Parameters
  • full_text – The full_text will be displayed by i3bar on the status line. This is the only required parameter. If full_text is an empty string, the block will be skipped.

  • short_text – It will be used in case the status line needs to be shortened because it uses more space than your screen provides.

  • color – To make the current state of the information easy to spot, colors can be used. Colors are specified in hex (like in HTML), starting with a leading hash sign. For example, #ff0000 means red.

  • background – Overrides the background color for this particular block.

  • border – Overrides the border color for this particular block.

  • border_top – Defines the width (in pixels) of the top border of this block. Defaults to 1.

  • border_right – Defines the width (in pixels) of the right border of this block. Defaults to 1.

  • border_bottom – Defines the width (in pixels) of the bottom border of this block. Defaults to 1.

  • border_left – Defines the width (in pixels) of the left border of this block. Defaults to 1.

  • min_width – The minimum width (in pixels) of the block. If the content of the full_text key take less space than the specified min_width, the block will be padded to the left and/or the right side, according to the align key.

  • align – Align text on the center, right or left (default) of the block, when the minimum width of the latter, specified by the min_width key, is not reached.

  • urgent – A boolean which specifies whether the current value is urgent.

  • separator – A boolean which specifies whether a separator line should be drawn after this block. The default is true, meaning the separator line will be drawn.

  • separator_block_width – The amount of pixels to leave blank after the block. In the middle of this gap, a separator line will be drawn unless separator is disabled.

  • markup – A string that indicates how the text of the block should be parsed. Pango markup only works if you use a pango font.

reset_state(self) None

Reset a block to default state.

Same as calling update_state() with None, but this makes the intetion clearer.

result(self) i3pyblocks._internal.models.State

Returns the current state of Block as a dict.

This will combine both the default state and the current state to generate the current state of the Block.

Returns

A State dict, ready to be converted to JSON.

push_update(self) None

Push result to queue, so it can be retrieved by Runner.

update(self, *args, **kwargs) None

Updates a Block.

This method will immediately updates a Block, so its new contents should be shown in the next redraw of i3bar. It is basically the equivalent of calling Method’s update_state() followed by push_update().

The parameters of this method is passed as-is to Block’s update_state().

abort(self, *args, **kwargs) None

Aborts a Block.

This method will do one last update of the Block, and disable all further updates on it. Useful to show errors.

Note that this does not necessary stops the Block from working (i.e.: its loop may still be running), it just stops the updates from showing in i3bar. Each Block is responsible to stop updating after this method is called, if this is desired.

The parameters of this method is passed as-is to Block’s update_state().

exception(self, exception: Exception, format: str = 'Exception in {block_name}: {exception}', reraise=True) None

Log and show the exception in i3bar.

Parameters
  • exception – Exception raised by block.

  • format – Format string to shown. Supports the {block_name} and {exception} placeholders

  • reraise – If the exception should be reraised. This should stop the block from working.

async setup(self, queue: Optional[asyncio.Queue] = None) None

Setup a Block.

This method is called just before start() to setup some things necessary to make the Block work.

If you want to do some kinda of async initialization, override this function and put your code here. However, do not forget to call await super().setup(queue=queue) after your code to prepare your Block for updates.

Parameters

queueasyncio.Queue instance that will be used to notify updates from this Block.

async click_handler(self, *, x: int, y: int, button: int, relative_x: int, relative_y: int, width: int, height: int, modifiers: List[Optional[str]]) None

Callback called when a click event happens to this Block.

Each of this method arguments is from click events in i3bar protocol since they’re mapped directly (so a {"x": 1} results in a x=1).

Parameters
  • x – X11 root window coordinates where the click occurred.

  • y – X11 root window coordinates where the click occurred.

  • button – X11 button ID (for example 1 to 3 for left/middle/right mouse button).

  • relative_x – Coordinates where the click occurred, with respect to the top left corner of the block.

  • relative_y – Coordinates where the click occurred, with respect to the top left corner of the block.

  • width – Width (in px) of the block.

  • height – Height (in px) of the block.

  • modifier – A list of the modifiers active when the click occurred. The order in which modifiers are listed is not guaranteed.

See also

i3pyblocks.types.MouseButton has the mapping of the available mouse button IDs.

i3pyblocks.types.KeyModifier has the mapping of the available modifiers.

async signal_handler(self, *, sig: signal.Signals) None

Callback called when a signal event happens to this Block.

Parameters

sigSignal enum with the signal that originated this event. This can be used to differentiate between different signals.

abstract async start(self) None

Starts a Block.

This is an abstract method, so it should be overriden.

This method is where you generally wants to put your main loop to update the state of the Block. This loop can either be triggered by events or can be an infinity loop. It can even be a single call to update(), but in this case your Block will only be updated once.

class i3pyblocks.blocks.base.PollingBlock(sleep: int = 1, **kwargs)

Bases: Block

Polling Block.

This is the most common Block implementation. It is a Block that runs a loop where it executes run() method and sleeps for sleep seconds, afterwards running run() again, keeping this cycle forever.

By default, a click or a signal event will refresh the contents of this Block.

You must not instantiate this class directly, instead you should subclass it and implement run() method first.

Parameters

sleep – Sleep in seconds between each call to run().

abstract async run(self) None

Main loop in PollingBlock.

This is the method that will be run at each X sleep seconds.

Since this is an abstract method, it should be overriden before usage.

async click_handler(self, **kwargs) None

Callback called when a click event happens to this Block.

Each of this method arguments is from click events in i3bar protocol since they’re mapped directly (so a {"x": 1} results in a x=1).

Parameters
  • x – X11 root window coordinates where the click occurred.

  • y – X11 root window coordinates where the click occurred.

  • button – X11 button ID (for example 1 to 3 for left/middle/right mouse button).

  • relative_x – Coordinates where the click occurred, with respect to the top left corner of the block.

  • relative_y – Coordinates where the click occurred, with respect to the top left corner of the block.

  • width – Width (in px) of the block.

  • height – Height (in px) of the block.

  • modifier – A list of the modifiers active when the click occurred. The order in which modifiers are listed is not guaranteed.

See also

i3pyblocks.types.MouseButton has the mapping of the available mouse button IDs.

i3pyblocks.types.KeyModifier has the mapping of the available modifiers.

async signal_handler(self, **kwargs) None

Callback called when a signal event happens to this Block.

Parameters

sigSignal enum with the signal that originated this event. This can be used to differentiate between different signals.

async start(self) None

Starts a Block.

This is an abstract method, so it should be overriden.

This method is where you generally wants to put your main loop to update the state of the Block. This loop can either be triggered by events or can be an infinity loop. It can even be a single call to update(), but in this case your Block will only be updated once.

class i3pyblocks.blocks.base.SyncBlock(executor: Optional[concurrent.futures.Executor] = None, **kwargs)

Bases: Block

Sync Block.

This is a special Block implementation to be used when it is not possible to implement functionality using asyncio, for example, when a external library uses its own event loop or its calls are synchronous and slow.

What this block does is to call start_sync() method inside an executor, that is run in a separate thread or process depending of the selected executor. Since it is running in a separate thread/process, it does not interfere with the main asyncio loop.

You must not instantiate this class directly, instead you should subclass it and implement start_sync() method first.

Parameters

executor – An optional Executor instance. If not passed it will use the default one.

async click_handler(self, **kwargs) None

Callback called when a click event happens to this Block.

Each of this method arguments is from click events in i3bar protocol since they’re mapped directly (so a {"x": 1} results in a x=1).

Parameters
  • x – X11 root window coordinates where the click occurred.

  • y – X11 root window coordinates where the click occurred.

  • button – X11 button ID (for example 1 to 3 for left/middle/right mouse button).

  • relative_x – Coordinates where the click occurred, with respect to the top left corner of the block.

  • relative_y – Coordinates where the click occurred, with respect to the top left corner of the block.

  • width – Width (in px) of the block.

  • height – Height (in px) of the block.

  • modifier – A list of the modifiers active when the click occurred. The order in which modifiers are listed is not guaranteed.

See also

i3pyblocks.types.MouseButton has the mapping of the available mouse button IDs.

i3pyblocks.types.KeyModifier has the mapping of the available modifiers.

async signal_handler(self, **kwargs) None

Callback called when a signal event happens to this Block.

Parameters

sigSignal enum with the signal that originated this event. This can be used to differentiate between different signals.

click_handler_sync(self, *, x: int, y: int, button: int, relative_x: int, relative_y: int, width: int, height: int, modifiers: List[Optional[str]]) None

Synchronous version of click_handler().

signal_handler_sync(self, *, sig: signal.Signals) None

Synchronous version of signal_handler().

abstract start_sync(self) None

Starts a synchronous Block.

This is an abstract method, so it should be overriden.

This method is where you generally wants to put your main loop to update the state of the Block. This loop can either be triggered by events or can be an infinity loop. It can even be a single call to update(), but in this case your Block will only be updated once.

async start(self) None

Starts a Block.

This is an abstract method, so it should be overriden.

This method is where you generally wants to put your main loop to update the state of the Block. This loop can either be triggered by events or can be an infinity loop. It can even be a single call to update(), but in this case your Block will only be updated once.

class i3pyblocks.blocks.base.PollingSyncBlock(sleep: int = 1, executor: Optional[concurrent.futures.Executor] = None, **kwargs)

Bases: SyncBlock

Polling sync Block.

This is a special Block implementation to be used when it is not possible to implement functionality using asyncio, for example, when a external library uses its own event loop or its calls are synchronous and slow.

It is a Block that runs a loop where it executes run_sync() method and sleeps for sleep seconds, afterwards running run_sync() again, keeping this cycle forever. Since it is running in a separate thread/process, it does not interfere with the main asyncio loop.

You must not instantiate this class directly, instead you should subclass it and implement run_sync() method first.

Parameters
  • executor – An optional Executor instance. If not passed it will use the default one.

  • sleep – Sleep in seconds between each call to run_sync().

click_handler_sync(self, **kwargs) None

Synchronous version of click_handler().

signal_handler_sync(self, **kwargs) None

Synchronous version of signal_handler().

abstract run_sync(self) None

Main loop in PollingSyncBlock.

This is the method that will be run at each X sleep seconds.

Since this is an abstract method, it should be overriden before usage.

start_sync(self) None

Starts a synchronous Block.

This is an abstract method, so it should be overriden.

This method is where you generally wants to put your main loop to update the state of the Block. This loop can either be triggered by events or can be an infinity loop. It can even be a single call to update(), but in this case your Block will only be updated once.