Defining own plugins

A platform is a Plugin: what it can do, which secrets it needs, and those calls. Real ones are packages (uv run task plugin:new -- <platform> <Class> "<description>") found through an entry point; here one is registered by hand, for this notebook.

import os

from amoorion import Amoorion

# A sandbox for this whole notebook: secrets only from variables, the inbox and
# the dataset in a temporary folder. Nothing here can touch your real setup.
Amoorion.init()
PosixPath('/tmp/amoorion-pecm67ua')
from datetime import UTC, datetime

from typing import ClassVar


from amoorion import Plugins

# What a plugin takes and answers.
from amoorion.models import Message, Post

# To register and to subclass.
from amoorion.plugins import PLUGINS, Capability, Plugin


# A whole platform: a name, what it can do, its secrets, and those operations.
class Notebook(Plugin):
    name: ClassVar[str] = "notebook"

    description: ClassVar[str] = "prints posts in the notebook"

    capabilities: ClassVar[frozenset[Capability]] = frozenset({Capability.POST})

    secrets: ClassVar[tuple[str, ...]] = ("greeting",)

    def post(
        self,
        post: Post,
    ) -> Message:

        text = f"{self.secret('greeting')}: {post.text}"

        print(text)

        return Message(
            platform=self.name,
            text=text,
            id="1",
            created_at=datetime.now(UTC),
        )


# In a package, an entry point does this by itself.
PLUGINS.register(Notebook)

# It is a platform like any other now.
Plugins["notebook"]
<Plug notebook unknown: post>

It now is like any other, secrets from the vault included:

# `creds` is false: its secret isn't set.
print(Plugins["notebook"].infoflags)

# Set it in the sandbox's variables.
os.environ["AMOORION_SECRET_NOTEBOOK_GREETING"] = "hello"

# Now it is.
print(Plugins["notebook"].infoflags["creds"])

# Together with another platform, by the same method.
Amoorion().use(Plugins["notebook"], "dryrun").publish(
    text="from my own plugin"
)[0]["ok"]
{'creds': False, 'can_post': True, 'can_read': False, 'can_reply': False, 'can_delete': False}
True
hello: from my own plugin
True

What it can’t do it refuses clearly:

# It never said it could read, so it refuses, clearly.
try:
    Amoorion().read(platform="notebook")

except Exception as error:
    print(
        type(error).__name__,
        "-",
        error,
    )
Unsupported - notebook can't read

Test a real plugin against a fake of its platform’s API, as every package in packages/ does. Guide: docs/plugins.md.