Skip to content

trading_agent.extensions.app_manifest

A package's app.toml: the web app it brings and the systemd unit that runs it.

An app is a separate program with its own web page, such as sridhara. trading-agent never runs it inside the gateway; it shows the page in its sidebar, checks that the page answers, and can start, stop or restart the app's systemd user unit.

[app] title = "Sridhara" description = "A Kite-style trading terminal on UBI" url = "http://127.0.0.1:8095/" health_url = "http://127.0.0.1:8095/" optional; the url itself when left out open_in = "frame" "frame" shows it inside trading-agent, "tab" opens a new tab

[service] optional unit = "sridhara.service" the systemd user unit that runs the app unit_file = "%h/Projects/sridhara/services/sridhara.service" optional; linked by trading-agent apps enable

Typical usage example:

manifest = AppManifestReader().read(package_folder / 'app.toml')

APP_FILE_NAME module-attribute

APP_FILE_NAME = 'app.toml'

AppManifestError

Bases: ValueError

An app.toml that cannot be read or holds invalid values.

AppSettings

Bases: BaseModel

The [app] table.

Attributes:

Name Type Description
title str

The name shown in the sidebar.

description str

One sentence about the app.

url AnyHttpUrl

The app's own web page.

health_url AnyHttpUrl | None

The address checked to say the app is up, or None to check the url.

open_in Literal['frame', 'tab']

"frame" to show the page inside trading-agent, "tab" to open it in a new tab.

ServiceSettings

Bases: BaseModel

The [service] table.

Attributes:

Name Type Description
unit str

The systemd user unit, such as sridhara.service.

unit_file str | None

The unit file trading-agent apps enable links, or None when the unit is installed already; %h stands for the home folder, and a relative path is inside the package.

AppManifest

Bases: BaseModel

A whole app.toml.

Attributes:

Name Type Description
app AppSettings

The web app.

service ServiceSettings | None

Its systemd unit, or None for an app trading-agent cannot start or stop.

health_address

health_address()

The address checked to say the app is up.

Returns:

Type Description
str

The health_url, or the url when there is none.

Source code in src/trading_agent/extensions/app_manifest.py
def health_address(self) -> str:
    """The address checked to say the app is up.

    Returns:
        str: The health_url, or the url when there is none.
    """
    return str(self.app.health_url or self.app.url)

unit_file_path

unit_file_path(package_folder)

Where the unit file is.

Parameters:

Name Type Description Default
package_folder Path

The installed package's folder.

required

Returns:

Type Description
Path | None

The unit file's path, or None when the manifest names none.

Source code in src/trading_agent/extensions/app_manifest.py
def unit_file_path(self, package_folder: Path) -> Path | None:
    """Where the unit file is.

    Args:
        package_folder (Path): The installed package's folder.

    Returns:
        Path | None: The unit file's path, or None when the manifest names none.
    """
    if self.service is None or self.service.unit_file is None:
        return None
    text = self.service.unit_file.replace(
        _HOME_PLACEHOLDER, str(Path.home())
    )
    path = Path(text)
    if not path.is_absolute():
        path = package_folder / path
    return path

AppManifestReader

Reads and checks app.toml files.

read

read(path)

Reads one app.toml.

Parameters:

Name Type Description Default
path Path

The file.

required

Returns:

Type Description
AppManifest

Its settings.

Raises:

Type Description
AppManifestError

The file is not valid TOML, or a value is missing or wrong.

Source code in src/trading_agent/extensions/app_manifest.py
def read(self, path: Path) -> AppManifest:
    """Reads one app.toml.

    Args:
        path (Path): The file.

    Returns:
        AppManifest: Its settings.

    Raises:
        AppManifestError: The file is not valid TOML, or a value is missing or wrong.
    """
    try:
        data = tomllib.loads(path.read_text(encoding='utf-8'))
    except (OSError, tomllib.TOMLDecodeError) as error:
        raise AppManifestError(f'{path}: {error}') from error
    try:
        return AppManifest.model_validate(data)
    except pydantic.ValidationError as error:
        problems = []
        for problem in error.errors():
            location = '.'.join(str(part) for part in problem['loc'])
            problems.append(f'{location}: {problem["msg"]}')
        raise AppManifestError(f'{path}: {"; ".join(problems)}') from error