Skip to main content

A flexible and robust Python library for creating, managing, and interacting with data services, with built-in support for web and RPC servers, and customizable features for diverse use cases.

Project description

pydase Banner

Version Python Versions Documentation Status License: MIT DOI

pydase is a Python library that simplifies the creation of remote control interfaces for Python objects. It exposes the public attributes of a user-defined class via a Socket.IO web server, ensuring they are always in sync with the service state. You can interact with these attributes using an RPC client, a RESTful API, or a web browser. The web browser frontend is auto-generated, displaying components that correspond to each public attribute of the class for direct interaction. pydase implements an observer pattern to provide the real-time updates, ensuring that changes to the class attributes are reflected across all clients.

Whether you're managing lab sensors, network devices, or any abstract data entity, pydase facilitates service development and deployment.

Features

Installation

Install pydase using poetry:

poetry add pydase

or pip:

pip install pydase

Usage

Using pydase involves three main steps: defining a pydase.DataService subclass, running the server, and then connecting to the service either programmatically using pydase.Client or through the web interface.

Defining a DataService

To use pydase, you'll first need to create a class that inherits from pydase.DataService. This class represents your custom service, which will be exposed via a web server.
Your class can implement synchronous and asynchronous methods, some built-in types (like int, float, str, bool, list or dict) and other components as attributes. For more information, please refer to the components guide.

Here's an example:

import pydase
from pydase.utils.decorators import frontend


class Device(pydase.DataService):
    _current = 0.0
    _voltage = 0.0
    _power = False

    @property
    def current(self) -> float:
        # run code to get current
        return self._current

    @current.setter
    def current(self, value: float) -> None:
        # run code to set current
        self._current = value

    @property
    def voltage(self) -> float:
        # run code to get voltage
        return self._voltage

    @voltage.setter
    def voltage(self, value: float) -> None:
        # run code to set voltage
        self._voltage = value

    @property
    def power(self) -> bool:
        # run code to get power state
        return self._power

    @power.setter
    def power(self, value: bool) -> None:
        # run code to set power state
        self._power = value

    @frontend
    def reset(self) -> None:
        self.current = 0.0
        self.voltage = 0.0


if __name__ == "__main__":
    service = Device()
    pydase.Server(service=service, web_port=8001).run()

In the above example, we define a Device class that inherits from pydase.DataService. We define a few properties (current, voltage, power) and their getter and setter methods.

Running the Server

Once your service class is defined, you can create an instance of it and run the server:

import pydase

# ... defining the Device class ...

if __name__ == "__main__":
    service = Device()
    pydase.Server(service=service, web_port=8001).run()

This will start the server, making your Device service accessible on http://localhost:8001. The port number for the web server can be customised in the server constructor or through environment variables and defaults to 8001.

Accessing the Web Interface

Once the server is running, you can access the web interface in a browser:

Web Interface

In this interface, you can interact with the properties of your Device service.

Connecting to the Service via Python RPC Client

You can connect to the service using the pydase.Client. Below is an example of how to establish a connection to a service and interact with it:

import pydase

# Replace the hostname and port with the IP address and the port of the machine where 
# the service is running, respectively
client_proxy = pydase.Client(url="ws://<ip_addr>:<web_port>").proxy
# client_proxy = pydase.Client(url="wss://your-domain.ch").proxy  # if your service uses ssl-encryption

# After the connection, interact with the service attributes as if they were local
client_proxy.voltage = 5.0
print(client_proxy.voltage)  # Expected output: 5.0

This example demonstrates setting and retrieving the voltage attribute through the client proxy. The proxy acts as a local representative of the remote service, enabling straightforward interaction.

The proxy class dynamically synchronizes with the server's exposed attributes. This synchronization allows the proxy to be automatically updated with any attributes or methods that the server exposes, essentially mirroring the server's API. This dynamic updating enables users to interact with the remote service as if they were working with a local object.

The RPC client also supports tab completion support in the interpreter, can be used as a context manager and integrates very well with other pydase services. For more information, please refer to the documentation.

RESTful API

The pydase RESTful API allows for standard HTTP-based interactions and provides access to various functionalities through specific routes.

For example, you can get a value like this:

import json

import requests

response = requests.get(
    "http://<hostname>:<web_port>/api/v1/get_value?access_path=<full_access_path>"
)
serialized_value = json.loads(response.text)

For more information, see here.

Configuring pydase via Environment Variables

pydase services work out of the box without requiring any configuration. However, you might want to change some options, such as the web server port or logging level. To accommodate such customizations, pydase allows configuration through environment variables, such as:

  • ENVIRONMENT:
    Defines the operation mode ("development" or "production"), which influences behaviour such as logging (see Logging in pydase).

  • SERVICE_CONFIG_DIR:
    Specifies the directory for configuration files (e.g., web_settings.json). Defaults to the config folder in the service root. Access this programmatically using:

    import pydase.config
    pydase.config.ServiceConfig().config_dir
    
  • SERVICE_WEB_PORT:
    Defines the web server’s port. Ensure each service on the same host uses a unique port. Default: 8001.

  • GENERATE_WEB_SETTINGS:
    When true, generates or updates the web_settings.json file. Existing entries are preserved, and new entries are appended.

For more information, see Configuring pydase.

Customizing the Web Interface

pydase allows you to enhance the user experience by customizing the web interface's appearance through

  1. a custom CSS file, and
  2. a custom favicon image, and
  3. tailoring the frontend component layout and display style.

You can also provide a custom frontend source if you need even more flexibility.

For details, please see here.

Logging in pydase

The pydase library provides structured, per-module logging with support for log level configuration, rich formatting, and optional client identification in logs.

To configure logging in your own service, you can use:

from pydase.utils.logging import configure_logging_with_pydase_formatter

For more information, see the full guide.

Documentation

The full documentation provides more detailed information about pydase, including advanced usage examples, API references, and tips for troubleshooting common issues. See the full documentation for more information.

Contributing

We welcome contributions! Please see contributing.md for details on how to contribute.

Acknowledgements

This work was funded by the ETH Zurich-PSI Quantum Computing Hub.

The main idea behind pydase is based on a previous project called tiqi-plugin, which was developed within the same research group. While the concept was inspired by that project, pydase was implemented from the ground up with a new architecture and design.

License

pydase is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydase-0.10.21.tar.gz (321.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydase-0.10.21-py3-none-any.whl (335.1 kB view details)

Uploaded Python 3

File details

Details for the file pydase-0.10.21.tar.gz.

File metadata

  • Download URL: pydase-0.10.21.tar.gz
  • Upload date:
  • Size: 321.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pydase-0.10.21.tar.gz
Algorithm Hash digest
SHA256 07d5467e51a7f7eab7067c0c12f6198a56a4012870d565b6ab5ffb600725b644
MD5 f8b09cb954473b6fc461ae41d2abe960
BLAKE2b-256 8ea902b65be5e85b6485a855bf73d4a0c107b84b06d3835a5c5d0d0d063b0d8b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydase-0.10.21.tar.gz:

Publisher: publish-to-pypi.yaml on tiqi-group/pydase

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydase-0.10.21-py3-none-any.whl.

File metadata

  • Download URL: pydase-0.10.21-py3-none-any.whl
  • Upload date:
  • Size: 335.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pydase-0.10.21-py3-none-any.whl
Algorithm Hash digest
SHA256 1c6450b01a2368e90454e85c686d7cb96ccb47a464b7515e844915bdbb3b3487
MD5 c07101bd32364d7b21ec95bad46676ce
BLAKE2b-256 0b2b2020864ff9d1a44b635ba36741ca542e88cab773d45c1b5f3ed260c43111

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydase-0.10.21-py3-none-any.whl:

Publisher: publish-to-pypi.yaml on tiqi-group/pydase

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page