Skip to main content

🛠️ Clyjin

Provides a core for building plugins with CLI interfaces.

👩‍🏭 Installation

If you want to install some plugin, you probably need only one command:

pip install clyjin_someplugin

Additional steps might be required, consult with plugin's documentation for details.

If you want to install Clyjin Core to develop own plugin, you might want to start with:

pip install clyjin

Or, using poetry:

poetry add clyjin

📓 Getting Started

To get grasp of Clyjin's functionality we'll develop a new plugin called Hello.

First, you need to create a new Python project which name starts with clyjin_, e.g. clyjin_hello.

Structure of the project might look like:

.
├── .venv
├── clyjin_hello/
│   ├── __init__.py
│   └── _main.py
├── poetry.lock
└── pyproject.toml

Main class of your plugin-project is Plugin. Clyjin on initialization makes imports of your defined plugin with statement like from clyjin_hello import MainPlugin.

This means you need to define a variable called MainPlugin in your __init__.py pointing to your plugin class:

# clyjin_hello/__init__.py
from clyjin_hello._main import HelloPlugin

MainPlugin = HelloPlugin

That said, our plugin can be defined wherever we want, but we should reference it to be importable from our root Python package via name MainPlugin.

The plugin itself in our example is defined within _main.py:

# clyjin_hello/main.py
from clyjin.base import Plugin, PluginInitializeData

class HelloPlugin(Plugin):
    Name = "hello"
    ModuleClasses = [
        RootModule,
        GreetingsModule
    ]
    # retrieve version of our package dynamically
    Version = importlib.metadata.version("clyjin_hello")

    @classmethod
    async def initialize(
        clas,
        data: PluginInitializeData
    ) -> None:
        # our custom initialization logic
        ...

Let's do a quick overview of the things happened here:

  • Name = "hello" - defines a callable name for our plugin. It will be used as a main entrypoint in CLI and in other references.
  • ModuleClasses = [...] - list of module classes defined for your plugin.
  • Version = importlib.metadata.version("clyjin_hello") - version of our plugin. In this case retrieved dynamically from package's data.
  • async def initialize(...) - extra initialization logic for our plugin.

Our plugin's modules can be defined as follows:

from clyjin.base import Module, ModuleData

class RootModule(Module[MyRootArgs, MyRootConfig]):
    Name = "$root"
    Description = "show count of hello words said"
    Args = MyRootArgs(
        output_dir=ModuleArg[str](
            names=["output_dir"],
            type=Path,
            help="where to write the result output"
        )
        is_world_only=ModuleArg[bool](
            names=["-w", "--world"],
            action="store_true",
            type=bool,
            argparse_type=type,
            help="whether should count only \"hello world\" messages"
        )
    )

    def __init__(
        self,
        module_data: ModuleData[MyRootArgs, MyRootConfig]
    ) -> None:
        super().__init__(module_data)

        # ... do whatever you want on your module's initialization
        # module data fields is available under self protected attributes,
        # e.g. self._args.output_dir or self._config as well as additional
        # helper variables, like self._rootdir

    async def execute(self) -> None:
        # ... called on module's execution
        # args values can be accessed like `self.args.output_dir.value`
        ...
  • class RootModule(Module[MyRootArgs, MyRootConfig]) - declares our module's class, inheriting it from generic module with setting as first argument our Args class and as second argument our Config class.
  • Name = "$root" - special name for a module indicates that this module is a root module. Root modules are called directly under Plugin's namespace, e.g. clyjin hello ..., while other modules are called like clyjin hello.module_name ....
  • Description = "..." - description of the module, appeared at least in CLI help output
  • Args = MyRootArgs(...) - initialization of our module's args class. Args class contains information about CLI arguments supported by our module. It's structure is mostly similar like arguments passed to argparse.add_argument.
  • def __init__(...) - initialization method of our module accepting ModuleData object as first argument. ModuleData contains information about args, config and some extra helper fields, such as rootdir. Insider our Module super class all these fields are set to protected instance's variables, like self._rootdir making them available for further usage.
  • async def execute(self) -> None - method called if Clyjin core decided to chose this module to execute next request. Typically, if you need to access CLI arguments passed within this method, you will need to use this.args.your_cli_arg.value statement.

You can define as many modules as you need in your Plugin.ModuleClasses field, but you can have only one root module, i.e. module with name $root, and other module names should be all unique.

To call your plugin anywhere, you need to install clyjin and clyjin_hello (i.e. your plugin) and issue a CLI command:

clyjin <your_plugin_name>.<your_module_name> <...arguments>

For example for our imaginary GreetingsModule, which is part of HelloPlugin, we might issue a command:

clyjin clyjin_hello.greetings --to world --from $USER

💪 Advanced

📁 System directories

[in process of writing, take some coffee ☕]

🔶 Official Plugins

Metadata

Release files for clyjin 0.2.12

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for clyjin 0.2.12
File Size Uploaded
clyjin-0.2.12.tar.gz 15.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for clyjin 0.2.12
File Interpreter ABI Platform
clyjin-0.2.12-py3-none-any.whl Python 3 none any Details

Total release size: 35.6 kB

Release files / clyjin-0.2.12.tar.gz

Download URL clyjin-0.2.12.tar.gz
Size 15.5 kB
Tags Source
SHA-256 checksum
How to use checksums
9f79775644594d11f428e9e1ad6cdd718deb989d839d43be16c7276e4bbc80a8
BLAKE2b-256 checksum
How to use checksums
64ac6e39694a1df0efbda605d17b3d73df9e0f71c8e43a0c6e2362b359e7303f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.5.1 CPython/3.11.5 Linux/6.5.5-zen1-1-zen

Release files / clyjin-0.2.12-py3-none-any.whl

Download URL clyjin-0.2.12-py3-none-any.whl
Size 20.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6496026a47864f5b24d226f0b346ed6025f1f981d4e5cfb6f6c6393f14824470
BLAKE2b-256 checksum
How to use checksums
f721ef5c03a7152bf08ccc17d8fe3b1accc9eb1a1bf9e454b65c6c59b2bb9967
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.5.1 CPython/3.11.5 Linux/6.5.5-zen1-1-zen

Release history Release notifications | RSS feed

This release

0.2.12 This release

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

1 release file

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page