What are plugins in Amoorion?

They are integration packages for making a bridge with community platforms, social services and mass-media channels (social media, mailing, webhooks etc.).

Plugins is the collection of what is installed, at rest: nothing is logged in to.

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-60dkr25_')
from amoorion import Plugins

# A helper for reading flags.
from amoorion.methods import plugsFlagsToList

# One platform: its name, version and what it can do.
Plugins["x"]
<Plug x 0.4.6: delete, post, read, reply>
# All of them; each platform is its own package.
Plugins
<Plugins blogger, bluesky, discord, discord-webhook, dryrun, email, facebook, mastodon, matrix, ntfy, telegram, tumblr, x>

A plugin in the collection is also its name, so a list of them is a list of names:

# Iterating gives plugs.
list(Plugins)
[<Plug blogger 0.4.4: post>,
 <Plug bluesky 0.4.5: delete, post, read, reply>,
 <Plug discord 0.4.5: delete, post, read, reply>,
 <Plug discord-webhook 0.4.5: delete, post>,
 <Plug dryrun 0.4.32a0: delete, post, read, reply>,
 <Plug email 0.4.10: post, read, reply>,
 <Plug facebook 0.4.4: delete, post, read, reply>,
 <Plug mastodon 0.4.6: delete, post, read, reply>,
 <Plug matrix 0.4.5: delete, post, read, reply>,
 <Plug ntfy 0.4.8: post, read>,
 <Plug telegram 0.4.5: delete, post, read, reply>,
 <Plug tumblr 0.4.5: delete, post, read>,
 <Plug x 0.4.6: delete, post, read, reply>]

dict gives the description, version and flags of each:

# `dict` gives the information of each, by name.
dict(Plugins)["bluesky"]
PlugInfo(description='Bluesky (AT Protocol): post, read, reply, delete', version='0.4.5', flags={'creds': False, 'can_post': True, 'can_read': True, 'can_reply': True, 'can_delete': True})

And iterated over, each knows more. creds says the vault holds its secrets:

# `creds` tells whether its secrets are set, `can_*` what it can do.
for platform in Plugins:
    print(
        platform.name
        + " "
        + ", ".join(plugsFlagsToList(platform.infoflags))
        + " ;;"
    )
blogger can_post ;;
bluesky can_post, can_read, can_reply, can_delete ;;
discord can_post, can_read, can_reply, can_delete ;;
discord-webhook can_post, can_delete ;;
dryrun creds, can_post, can_read, can_reply, can_delete ;;
email can_post, can_read, can_reply ;;
facebook can_post, can_read, can_reply, can_delete ;;
mastodon can_post, can_read, can_reply, can_delete ;;
matrix can_post, can_read, can_reply, can_delete ;;
ntfy can_post, can_read ;;
telegram can_post, can_read, can_reply, can_delete ;;
tumblr can_post, can_read, can_delete ;;
x can_post, can_read, can_reply, can_delete ;;

use chooses what an object works on, one by one or together:

amo = Amoorion()

# `use` answers the object, so it chains…
amo.use(Plugins["x"]).use(Plugins["bluesky"]).use(Plugins["tumblr"])

print(amo.used)

# …or takes several at once.
print(
    Amoorion()
    .use(
        Plugins["x"],
        Plugins["bluesky"],
        Plugins["tumblr"],
    )
    .used
)
['x', 'bluesky', 'tumblr']
['x', 'bluesky', 'tumblr']

One platform failing doesn’t stop the others. These have no secrets here, so they refuse; dryrun needs none:

# Plain strings work too. x has no secrets in this sandbox.
publishing_results = (
    Amoorion()
    .use(
        "x",
        "dryrun",
    )
    .publish(text="hello")
)

# One failure doesn't stop the rest: each platform has its own result.
for result in publishing_results:
    print(
        result["platform"],
        "ok" if result["ok"] else result["error"],
    )
x secret 'x/api-key' not found (set AMOORION_SECRET_X_API_KEY)
dryrun ok

Every package is separate: pip install amoorion-bluesky adds one platform, found through the entry point group amoorion.plugins.