streamdeck-plugin-sdk


Namestreamdeck-plugin-sdk JSON
Version 0.4.0 PyPI version JSON
download
home_pageNone
SummaryWrite Streamdeck plugins using Python
upload_time2024-11-14 22:02:58
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT License Copyright (c) 2024 strohganoff Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords example project setup
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Python Stream Deck Plugin SDK

<p align="center">
    <em>Stream Deck SDK for Python plugins, easy to learn, fast to code</em>
</p>

---

A Python library for developing plugins for the Elgato Stream Deck. This library simplifies the process of creating Stream Deck plugins by providing classes and methods to handle WebSocket communication, event registration, and command sending.

This library differs from the official Stream Deck TypeScript SDK, as it aims to be more Pythonic, adhering to current Python conventions and trends. The goal is to make plugin development as simple and intuitive as possible for Python developers. Inspired by libraries like FastAPI, this project aims to provide a clear, concise, and developer-friendly experience for Python Stream Deck plugin development.


## Features

- **WebSocket Abstraction**: WebSocket communication is abstracted away, so users don't need to handle WebSocket connections directly.

- **Event Hooks**: Users simply define actions and their hooks that get automatically routed and called every time the Stream Deck sends the appropriate event. No need to subclass abstract Action classes.

- **Event Models**: Events received from the Stream Deck are fully modeled and typed using Pydantic, allowing for validation and making them easier to work with and develop against.

- **PluginManager**: Orchestrates action lifecycle, event-routing, and context-gathering behind the scenes.

## Installation

You can install the library via pip:

```bash
pip install streamdeck-plugin-sdk
```

## Getting Started

This guide will help you set up your first Stream Deck plugin using the library.

### Prerequisites

- Python 3.8 or higher
- Stream Deck software installed
- A valid `manifest.json` file for your plugin

### Creating an Action

An **Action** represents a specific functionality in your plugin. You can create multiple actions, each with its own set of event handlers.

```python
from streamdeck import Action

# Create an action with a unique UUID (from your manifest.json)
my_action = Action(uuid="com.example.myplugin.myaction")
```

### Registering Event Handlers

Use the `.on()` method to register event handlers for specific events.

```python
@my_action.on("keyDown")
def handle_key_down(event):
    print("Key Down event received:", event)

@my_action.on("willAppear")
def handle_will_appear(event):
    print("Will Appear event received:", event)
```

!!!INFO Handlers for action-specific events are dispatched only if the event is triggered by the associated action, ensuring isolation and predictability. For other types of events that are not associated with a specific action, handlers are dispatched without such restrictions.



### Writing Logs

For convenience, a logger is configured with the same name as the last part of the Action's UUID, so you can simply call logging.getLogger(<name>) with the appropriate name to get the already-configured logger that writes to a rotating file. The log file is located in the Stream Deck user log directory.

When creating actions in your plugin, you can configure logging using the logger name that matches the last part of your Action's UUID. For example, consider the following code:

```python
import logging
from streamdeck import Action

logger = logging.getLogger("myaction")

my_action = Action(uuid="com.example.mytestplugin.myaction")
```

Here, the logger name "myaction" matches the last part of the UUID passed in to instantiate the Action ("com.strohganoff.mytestplugin.myaction"). 

#### Configuring your own Loggers

Loggers can also be easily configured using provided utility functions, allowing for flexibility. If custom logging configurations are prefered over the automatic method shown above, you can use the following functions:

`configure_streamdeck_logger`: Configures a logger for the Stream Deck plugin with a rotating file handler that writes logs to a centralized location.

`configure_local_logger`: Configures a logger for a Stream Deck plugin that writes logs to a local data directory, allowing for plugin-specific logging.

These functions can be used to set up the logging behavior you desire, depending on whether you want the logs to be centralized or specific to each plugin.

For example:
```python
import logging
from streamdeck.utils.logging import configure_streamdeck_logger

configure_streamdeck_logger(name="myaction", plugin_uuid="com.example.mytestplugin")

logger = logging.getLogger("myaction")
```

Using the above code, you can ensure that logs from your action are properly collected and managed, helping you debug and monitor the behavior of your Stream Deck plugins.


### Running the Plugin

Once the plugin's actions and their handlers have been defined, very little else is needed to get this code running. With this library installed, the streamdeck CLI command   will handle the setup, loading of action scripts, and running of the plugin automatically, making it much easier to manage.

#### Usage

The following commands are required, which are the same as the Stream Deck software passes in when running a plugin:

- `-port`: The port number assigned by the Stream Deck.

- `-pluginUUID`: Your plugin's unique identifier, provided by the Stream Deck.

- `-registerEvent`: The event used to register your plugin. 

- `-info`: Additional information (formatted as json) about the plugin environment, as provided by the Stream Deck software.

There are also  two additional options for specifying action scripts to load. Note that you can't use both of these options together, and the Stream Deck software doesn't pass in these options.

- Plugin Directory: Pass the directory containing the plugin files as a positional argument:

    ```bash
    streamdeck myplugin_dir/
    ```
    This will read the pyproject.toml file inside the directory to locate the action scripts. If this is not passed in, then the library looks in the current working directory for a pyproject.toml file.

- Action Scripts Directly: Alternatively, pass the script paths directly using the `--action-scripts` option:

    ```bash
    streamdeck --action-scripts actions1.py actions2.py
    ```


#### Configuration

To configure your plugin to use the streamdeck CLI, add a tool.streamdeck section to your pyproject.toml with a list variable for action_scripts that should contain paths to all the action scripts you want the plugin to load.

Below is an example of the pyproject.toml configuration and how to run the plugin:
```toml
# pyproject.toml

[tools.streamdeck]
    action_scripts = [
        "actions1.py",
        "actions2.py",
    ]
```

## Simple Example

Below is a complete example that creates a plugin with a single action. The action handles the `keyDown` event and simply prints a statement that the event occurred.

```python
# main.py
import logging
from streamdeck import Action, PluginManager, events

logger = logging.getLogger("myaction")

# Define your action
my_action = Action(uuid="com.example.myplugin.myaction")

# Register event handlers
@my_action.on("keyDown")
def handle_key_down(event):
    logger.debug("Key Down event received:", event)
```

```toml
# pyproject.toml
[tools.streamdeck]
    action_scripts = [
        "main.py",
    ]
```
And a command like the following is called by the Stream Deck software:
```bash
streamdeck -port 28196 -pluginUUID 63831042F4048F072B096732E0385245 -registerEvent registerPlugin -info '{"application": {...}, "plugin": {"uuid": "my-plugin-name", "version": "1.1.3"}, ...}'
```


## Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub. See the [development.md](development.md) for setting up and testing the project.


## Upcoming Improvements

The following upcoming improvements are in the works:

- **Improved Documentation**: Expand and improve the documentation with more examples, guides, and use cases.
- **Bind Command Sender**: Automatically bind `command_sender` and action instance context-holding objects to handler function arguments if they are included in the definition.
- **Optional Event Pattern Matching on Hooks**: Add support for optional pattern-matching on event messages to further filter when hooks get called.
- **Async Support**: Introduce asynchronous features to handle WebSocket communication more efficiently.


## License

This project is licensed under the MIT License.


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "streamdeck-plugin-sdk",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "example, project, setup",
    "author": null,
    "author_email": "strohganoff <you@example.com>",
    "download_url": "https://files.pythonhosted.org/packages/21/e3/e37f51511b25a4757f8fd82d2a7554ea863978a158d2c2d3b7e76644f657/streamdeck_plugin_sdk-0.4.0.tar.gz",
    "platform": null,
    "description": "# Python Stream Deck Plugin SDK\n\n<p align=\"center\">\n    <em>Stream Deck SDK for Python plugins, easy to learn, fast to code</em>\n</p>\n\n---\n\nA Python library for developing plugins for the Elgato Stream Deck. This library simplifies the process of creating Stream Deck plugins by providing classes and methods to handle WebSocket communication, event registration, and command sending.\n\nThis library differs from the official Stream Deck TypeScript SDK, as it aims to be more Pythonic, adhering to current Python conventions and trends. The goal is to make plugin development as simple and intuitive as possible for Python developers. Inspired by libraries like FastAPI, this project aims to provide a clear, concise, and developer-friendly experience for Python Stream Deck plugin development.\n\n\n## Features\n\n- **WebSocket Abstraction**: WebSocket communication is abstracted away, so users don't need to handle WebSocket connections directly.\n\n- **Event Hooks**: Users simply define actions and their hooks that get automatically routed and called every time the Stream Deck sends the appropriate event. No need to subclass abstract Action classes.\n\n- **Event Models**: Events received from the Stream Deck are fully modeled and typed using Pydantic, allowing for validation and making them easier to work with and develop against.\n\n- **PluginManager**: Orchestrates action lifecycle, event-routing, and context-gathering behind the scenes.\n\n## Installation\n\nYou can install the library via pip:\n\n```bash\npip install streamdeck-plugin-sdk\n```\n\n## Getting Started\n\nThis guide will help you set up your first Stream Deck plugin using the library.\n\n### Prerequisites\n\n- Python 3.8 or higher\n- Stream Deck software installed\n- A valid `manifest.json` file for your plugin\n\n### Creating an Action\n\nAn **Action** represents a specific functionality in your plugin. You can create multiple actions, each with its own set of event handlers.\n\n```python\nfrom streamdeck import Action\n\n# Create an action with a unique UUID (from your manifest.json)\nmy_action = Action(uuid=\"com.example.myplugin.myaction\")\n```\n\n### Registering Event Handlers\n\nUse the `.on()` method to register event handlers for specific events.\n\n```python\n@my_action.on(\"keyDown\")\ndef handle_key_down(event):\n    print(\"Key Down event received:\", event)\n\n@my_action.on(\"willAppear\")\ndef handle_will_appear(event):\n    print(\"Will Appear event received:\", event)\n```\n\n!!!INFO Handlers for action-specific events are dispatched only if the event is triggered by the associated action, ensuring isolation and predictability. For other types of events that are not associated with a specific action, handlers are dispatched without such restrictions.\n\n\n\n### Writing Logs\n\nFor convenience, a logger is configured with the same name as the last part of the Action's UUID, so you can simply call logging.getLogger(<name>) with the appropriate name to get the already-configured logger that writes to a rotating file. The log file is located in the Stream Deck user log directory.\n\nWhen creating actions in your plugin, you can configure logging using the logger name that matches the last part of your Action's UUID. For example, consider the following code:\n\n```python\nimport logging\nfrom streamdeck import Action\n\nlogger = logging.getLogger(\"myaction\")\n\nmy_action = Action(uuid=\"com.example.mytestplugin.myaction\")\n```\n\nHere, the logger name \"myaction\" matches the last part of the UUID passed in to instantiate the Action (\"com.strohganoff.mytestplugin.myaction\"). \n\n#### Configuring your own Loggers\n\nLoggers can also be easily configured using provided utility functions, allowing for flexibility. If custom logging configurations are prefered over the automatic method shown above, you can use the following functions:\n\n`configure_streamdeck_logger`: Configures a logger for the Stream Deck plugin with a rotating file handler that writes logs to a centralized location.\n\n`configure_local_logger`: Configures a logger for a Stream Deck plugin that writes logs to a local data directory, allowing for plugin-specific logging.\n\nThese functions can be used to set up the logging behavior you desire, depending on whether you want the logs to be centralized or specific to each plugin.\n\nFor example:\n```python\nimport logging\nfrom streamdeck.utils.logging import configure_streamdeck_logger\n\nconfigure_streamdeck_logger(name=\"myaction\", plugin_uuid=\"com.example.mytestplugin\")\n\nlogger = logging.getLogger(\"myaction\")\n```\n\nUsing the above code, you can ensure that logs from your action are properly collected and managed, helping you debug and monitor the behavior of your Stream Deck plugins.\n\n\n### Running the Plugin\n\nOnce the plugin's actions and their handlers have been defined, very little else is needed to get this code running. With this library installed, the streamdeck\u00a0CLI command   will handle the setup, loading of action scripts, and running of the plugin automatically, making it much easier to manage.\n\n#### Usage\n\nThe following commands are required, which are the same as the Stream Deck software passes in when running a plugin:\n\n- `-port`: The port number assigned by the Stream Deck.\n\n- `-pluginUUID`: Your plugin's unique identifier, provided by the Stream Deck.\n\n- `-registerEvent`: The event used to register your plugin.\u00a0\n\n- `-info`: Additional information (formatted as json) about the plugin environment, as provided by the Stream Deck software.\n\nThere are also  two additional options for specifying action scripts to load. Note that you can't use both of these options together, and the Stream Deck software doesn't pass in these options.\n\n- Plugin Directory: Pass the directory containing the plugin files as a positional argument:\n\n    ```bash\n    streamdeck myplugin_dir/\n    ```\n    This will read the pyproject.toml file inside the directory to locate the action scripts. If this is not passed in, then the library looks in the current working directory for a pyproject.toml file.\n\n- Action Scripts Directly: Alternatively, pass the script paths directly using the `--action-scripts` option:\n\n    ```bash\n    streamdeck --action-scripts actions1.py actions2.py\n    ```\n\n\n#### Configuration\n\nTo configure your plugin to use the streamdeck CLI, add a tool.streamdeck section to your pyproject.toml\u00a0with a list variable for\u00a0action_scripts\u00a0that should contain paths to all the action scripts you want the plugin to load.\n\nBelow is an example of the pyproject.toml configuration and how to run the plugin:\n```toml\n# pyproject.toml\n\n[tools.streamdeck]\n    action_scripts = [\n        \"actions1.py\",\n        \"actions2.py\",\n    ]\n```\n\n## Simple Example\n\nBelow is a complete example that creates a plugin with a single action. The action handles the `keyDown` event and simply prints a statement that the event occurred.\n\n```python\n# main.py\nimport logging\nfrom streamdeck import Action, PluginManager, events\n\nlogger = logging.getLogger(\"myaction\")\n\n# Define your action\nmy_action = Action(uuid=\"com.example.myplugin.myaction\")\n\n# Register event handlers\n@my_action.on(\"keyDown\")\ndef handle_key_down(event):\n    logger.debug(\"Key Down event received:\", event)\n```\n\n```toml\n# pyproject.toml\n[tools.streamdeck]\n    action_scripts = [\n        \"main.py\",\n    ]\n```\nAnd a command like the following is called by the Stream Deck software:\n```bash\nstreamdeck -port 28196 -pluginUUID 63831042F4048F072B096732E0385245 -registerEvent registerPlugin -info '{\"application\": {...}, \"plugin\": {\"uuid\": \"my-plugin-name\", \"version\": \"1.1.3\"}, ...}'\n```\n\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request on GitHub. See the [development.md](development.md) for setting up and testing the project.\n\n\n## Upcoming Improvements\n\nThe following upcoming improvements are in the works:\n\n- **Improved Documentation**: Expand and improve the documentation with more examples, guides, and use cases.\n- **Bind Command Sender**: Automatically bind `command_sender` and action instance context-holding objects to handler function arguments if they are included in the definition.\n- **Optional Event Pattern Matching on Hooks**: Add support for optional pattern-matching on event messages to further filter when hooks get called.\n- **Async Support**: Introduce asynchronous features to handle WebSocket communication more efficiently.\n\n\n## License\n\nThis project is licensed under the MIT License.\n\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2024 strohganoff  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "Write Streamdeck plugins using Python",
    "version": "0.4.0",
    "project_urls": {
        "Homepage": "https://github.com/strohganoff/python-streamdeck-plugin-sdk",
        "Repository": "https://github.com/strohganoff/python-streamdeck-plugin-sdk"
    },
    "split_keywords": [
        "example",
        " project",
        " setup"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a7bee706d1c8d1c7092e6486d5f707c95ce2acd867c520295c065cc6d7ba9f26",
                "md5": "685e2cca93a4ce1086427b9a6819d1ac",
                "sha256": "845f9076d833e3e54629823747814a265e0de2cf10135a8260d48a3a27d0999e"
            },
            "downloads": -1,
            "filename": "streamdeck_plugin_sdk-0.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "685e2cca93a4ce1086427b9a6819d1ac",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 24609,
            "upload_time": "2024-11-14T22:02:56",
            "upload_time_iso_8601": "2024-11-14T22:02:56.310169Z",
            "url": "https://files.pythonhosted.org/packages/a7/be/e706d1c8d1c7092e6486d5f707c95ce2acd867c520295c065cc6d7ba9f26/streamdeck_plugin_sdk-0.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "21e3e37f51511b25a4757f8fd82d2a7554ea863978a158d2c2d3b7e76644f657",
                "md5": "a9d2580bd4855f986943c8f8f28e9e92",
                "sha256": "ecbb94149ad1e009ffea29de8716563e3e61312eeb19b35fd8b994c6a9a171dd"
            },
            "downloads": -1,
            "filename": "streamdeck_plugin_sdk-0.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "a9d2580bd4855f986943c8f8f28e9e92",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 31246,
            "upload_time": "2024-11-14T22:02:58",
            "upload_time_iso_8601": "2024-11-14T22:02:58.301236Z",
            "url": "https://files.pythonhosted.org/packages/21/e3/e37f51511b25a4757f8fd82d2a7554ea863978a158d2c2d3b7e76644f657/streamdeck_plugin_sdk-0.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-14 22:02:58",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "strohganoff",
    "github_project": "python-streamdeck-plugin-sdk",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "streamdeck-plugin-sdk"
}
        
Elapsed time: 0.36705s