From cede9973bee8918f95a429b1b178515129c87614 Mon Sep 17 00:00:00 2001 From: Felix Lorenz Date: Fri, 24 Nov 2023 12:15:22 +0100 Subject: [PATCH] Improve documentation (#3) --- README.md | 7 ++-- docs/development/libraryplugindev.md | 60 +++++++++++++++------------- docs/development/plugindev.md | 11 ++--- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 5d7a808..f764140 100644 --- a/README.md +++ b/README.md @@ -96,9 +96,8 @@ and then run it using nendo: from nendo import Nendo nd = Nendo(plugins=["nendo_plugin_musicgen"]) -song = nd.plugins.musicgen(prompt="funky 70s disco", bpm=120) -song.export("funky_disco.mp3") - +songs = nd.plugins.musicgen(prompt="funky 70s disco", bpm=120) +songs[0].export("funky_disco.mp3") ``` Please refer to the [documentation](https://okio.ai/docs/usage/) to learn more about how to use nendo. @@ -117,7 +116,7 @@ Nendo thrives on its rich [plugin](https://okio.ai/docs/plugins) ecosystem. Ther - Audio Quantization - Audio Loop-Extraction -If you want to develop your own plugin for nendo, consult the [plugin development documentation](https://okio.ai/docs/development/pluginsdev/), you'll be surprised how simple it is. +If you want to develop your own plugin for nendo, consult the [plugin development documentation](https://okio.ai/docs/development/plugindev/), you'll be surprised how simple it is. ## Contributors diff --git a/docs/development/libraryplugindev.md b/docs/development/libraryplugindev.md index e8cc88e..6800821 100644 --- a/docs/development/libraryplugindev.md +++ b/docs/development/libraryplugindev.md @@ -1,8 +1,8 @@ # Writing a `LibraryPlugin` -We'll go step by step through all the files you need to create and what they'll do. +Writing a `LibraryPlugin` differs significantly from implementing any of the other plugin types. It requires the implementation of all functions defined by the `NendoLibraryPlugin`, which can be found in the [API Reference](https://okio.ai/docs/reference/schema/plugin/#nendo.schema.plugin.NendoLibraryPlugin). The following is a preliminary introduction and will be heavily extended in the future. -Remember the directory structure from before: +The plugin's directory structure is exactly the same as with any other kind of plugin: ```shell ├── README.md @@ -15,19 +15,37 @@ Remember the directory structure from before: │   └── plugin.py ``` -Let's look into the different files now. - ## Files ### plugin.py -The most important thing in your plugin. Here is where all your magic happens. -Below, you'll find a simple implementation that just implements the library initializationa method. -We'll go through it step by step. +Below, you'll find a simple implementation that just implements the library initialization method and the `play()` method. + +- To implement a new library plugin, you have two options: + + 1. Inherit from the `SqlAlchemyNendoLibrary`, if your taget DBMS is compatible with SQLAlchemy, i.e. an SQLAlchemy driver exists for it. In this case, you only have to implement the initialization of the library as shown above. + 1. Inherit from the `NendoLibraryPlugin`, and implement a general library plugin that does not use SQLAlchemy to connect to the DBMS backend. In this case, you have to implement/override all public methods defined in the `NendoLibraryPlugin`. Refer to the [API Reference](https://okio.ai/docs/reference/schema/plugin/#nendo.schema.plugin.NendoLibraryPlugin) to see the full list of functions that have to be implemented. + +Below, we show how to implement a nendo library that uses the first approach, inheriting from the `SqlAlchemyNendoLibrary` plugin and implementing a `MongoDB` backend. ```python from logging import Logger -from nendo import Nendo, NendoConfig, SqlAlchemyNendoLibrary, NendoStorageLocalFS, NendoTrack +from nendo import ( + NendoConfig, + NendoStorage, + NendoStorageLocalFS, + NendoUser, + SqlAlchemyNendoLibrary, +) +from sqlalchemy import Engine, MetaData, create_engine +from sqlalchemy.orm import declarative_base + +from .config import MongoDBConfig + +plugin_package = metadata.metadata(__package__ or __name__) +plugin_config = MongoDBConfig() +Base = declarative_base(metadata=MetaData()) +logger = logging.getLogger("nendo") class MongoDBLibrary(SqlAlchemyNendoLibrary): @@ -71,25 +89,12 @@ class MongoDBLibrary(SqlAlchemyNendoLibrary): Base.metadata.create_all(bind=self.db) self.user = self.default_user return None - - def play(self, track: schema.NendoTrack) -> None: - """Preview an audio track on mac & linux. - - Args: - track (NendoTrack): The track to play. - """ - play_signal(track.signal, track.sr) - ``` The basics are very simple: -- To implement a new library plugin, you have two options:a - 1. Inherit from the `SqlAlchemyNendoLibrary`, if your taget DBMS is compatible with SQLAlchemy, i.e. an SQLAlchemy driver exists for it. In this case, you only have to implement the initialization of the library as shown bove. - 1. Inherit from the `NendoLibraryPlugin`, and implement a general library plugin that does not use SQLAlchemy to connect to the DBMS backend. In this case, you have to implement/override all public methods defined in the `NendoLibraryPlugin`. Refer to the [API Reference](https://okio.ai/docs/reference/schema/plugin/#nendo.schema.plugin.NendoLibraryPlugin) to see the full list of functions that have to be implemented.a -- Use nendo's `NendoStorageLocalFS` storage driver or implement your own. -- Overwrite any methods whose behavior you want to change -- Make sure that your implementation of the nendo library passes the library tests defined in `tests/test_library.py`. +- Use nendo's `NendoStorageLocalFS` storage driver or implement your own. Refer to the [API reference](https://okio.ai/docs/reference/schema/core/#nendo.schema.core.NendoStorage) to see which methods you need to implement for a `StorageDriver` to work. +- Overwrite any methods whose behavior you want to change but make sure that your implementation of the nendo library passes the library tests defined in `tests/test_library.py`. ### config.py @@ -97,15 +102,14 @@ The basics are very simple: from nendo import NendoConfig -class MongoDBLibraryConfig(NendoConfig): +class MongoDBConfig(NendoConfig): """Configuration defaults for the mongodb library plugin.""" model_config = ConfigDict(arbitrary_types_allowed=True) my_default_param: bool = False ``` -This class extends the base `NendoConfig` and allows you to define some default and overridable parameters for your -plugin. +This class extends the base `NendoConfig` and allows you to define some default and overridable parameters for your plugin. It behaves just like `NendoConfig`, read up more on basic `nendo` configuration [here](../usage/config.md). ### setup.py @@ -117,13 +121,13 @@ if __name__ == "__main__": setup( name="nendo-plugin-library-mongodb", version="0.1.0", - description="Nendo mongodb librarya plugin", + description="Nendo mongodb library plugin", author="Felix Lorenz ", ) ``` This is a standard `setup.py` file. -You can read up more on how tao configure it [here](https://packaging.python.org/tutorials/packaging-projects/). +You can read up more on how to configure it [here](https://packaging.python.org/tutorials/packaging-projects/). You just need to define some basics like the name of your plugin, a version number and a description. ### pyproject.toml diff --git a/docs/development/plugindev.md b/docs/development/plugindev.md index 2e1c91f..df6ea4b 100644 --- a/docs/development/plugindev.md +++ b/docs/development/plugindev.md @@ -45,13 +45,14 @@ In nendo we currently differentiate between four types of plugins. !!! warning Library plugins are a special type of plugin, they differ a lot from other plugins and should only be used if you know what you are doing. - Plugins that add new or completely different functionality to the `NendoLibrary` are called library plugins. + Plugins that implement new DBMS backends for the nendo library are called _library plugins_. To implement a new library plugin, you have two options: - TODO write more here Felix please, thanks - - Examples: + 1. Inherit from the `SqlAlchemyNendoLibrary`, if your taget DBMS is compatible with SQLAlchemy, i.e. an SQLAlchemy driver exists for it. In this case, you only have to implement the initialization of the library as shown bove. + 1. Inherit from the `NendoLibraryPlugin`, and implement a general library plugin that does not use SQLAlchemy to connect to the DBMS backend. In this case, you have to implement/override all public methods defined in the `NendoLibraryPlugin`. Refer to the [API Reference](https://okio.ai/docs/reference/schema/plugin/#nendo.schema.plugin.NendoLibraryPlugin) to see the full list of functions that have to be implemented. + + Examples: - - [nendo_plugin_library_postgres](https://github.com/okio-ai/nendo_plugin_library_postgres) + - [duckdb_library](https://okio.ai/docs/reference/library/duckdb_library/) !!! note Make sure that you understand the different plugin types before you start writing your own plugin.