### Setup Virtual Environment and Install Dependencies Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md Commands to create, activate, and install dependencies for a virtual environment using uv. Includes running the customization script and verifying the setup with tox. ```bash # Create virtual environment uv venv # Activate it source .venv/bin/activate # Install dependencies uv sync --all-extras # Run customization ./bin/customize.sh my-plugin --author "Name" --email "email@domain.com" # Verify setup tox ``` -------------------------------- ### Set Up Development Environment Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Installs dependencies and runs a customization script to set up your plugin repository. Ensure you have uv installed. ```bash uv venv source .venv/bin/activate uv sync --all-extras ./bin/customize.sh \ --author "Your Name" \ --email "your@email.com" \ --description "Your plugin description" \ --repository-url "https://github.com/your-org/your-repo" ``` -------------------------------- ### Initial Project Setup with UV and Tox Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/configuration.md Commands to set up a new virtual environment using uv, activate it, install all dependencies including extras, and run initial tests. ```bash uv venv source .venv/bin/activate uv sync --all-extras tox ``` -------------------------------- ### Set Up Virtual Environment and Install Dependencies Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/CONTRIBUTING.md Create a virtual environment using uv, activate it, and install all project dependencies including extras. ```bash uv venv source .venv/bin/activate uv sync --all-extras ``` -------------------------------- ### Verify Plugin Setup Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/README.md Commands to set up a virtual environment, install dependencies, and run tests using uv and tox. This verifies the plugin setup and checks for placeholder strings. ```bash uv venv && source .venv/bin/activate && uv sync --all-extras && tox ``` -------------------------------- ### Import Example After Package Installation Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Demonstrates that imports function identically after the plugin is installed via pip, using the customized package name. ```python from myorg.feature_groups.my_plugin import MyFeatureGroup ``` -------------------------------- ### Install Dependencies with uv Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/CLAUDE.md Installs all project dependencies, including extras, using the `uv` package manager. This command should be run after activating the virtual environment. ```bash uv sync --all-extras ``` -------------------------------- ### Instantiate MyExtender Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/extenders.md Example of creating an instance of the MyExtender class. ```python from placeholder.extenders.my_plugin import MyExtender # Create an extender instance extender = MyExtender() ``` -------------------------------- ### Namespace Package Init Files Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Provides examples of __init__.py files for namespace packages like feature_groups, compute_frameworks, and extenders. ```python # placeholder/feature_groups/__init__.py """Feature groups namespace package.""" # placeholder/compute_frameworks/__init__.py """Compute frameworks namespace package.""" # placeholder/extenders/__init__.py """Extenders namespace package.""" ``` -------------------------------- ### Plugin Registration Example Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/feature-groups.md Exports `MyFeatureGroup` from the `__init__.py` file to make it discoverable by the mloda framework. ```python # placeholder/feature_groups/my_plugin/__init__.py from placeholder.feature_groups.my_plugin.my_feature_group import MyFeatureGroup __all__ = ["MyFeatureGroup"] ``` -------------------------------- ### Namespace Package Structure Example Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Illustrates the recommended structure for namespace packages, using organization name, plugin type, and plugin name. ```tree myorg/ ├── feature_groups/ │ ├── sales/ │ ├── customers/ │ └── products/ ├── compute_frameworks/ │ ├── spark/ │ └── ray/ └── extenders/ ├── monitoring/ └── caching/ ``` -------------------------------- ### Version Bumping Examples Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md Examples of version bumping conventions used for semantic versioning. These are typically configured in `.releaserc.yaml` and automated by semantic-release. ```text 0.3.4 → 0.4.0 (feat:) 0.3.4 → 0.3.5 (fix:, chore:, docs:, test:, etc.) ``` -------------------------------- ### Template Example Structure Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Shows the concrete file and directory names in the mloda-plugin-template before customization. ```text placeholder/ ├── __init__.py # Empty root package ├── feature_groups/ │ ├── __init__.py # Contains: """Feature groups namespace package.""" │ └── my_plugin/ │ ├── __init__.py # Exports MyFeatureGroup │ ├── my_feature_group.py # MyFeatureGroup class │ └── tests/ │ ├── __init__.py # Empty test module │ └── test_my_feature_group.py ├── compute_frameworks/ │ ├── __init__.py # Contains: """Compute frameworks namespace package.""" │ └── my_plugin/ │ ├── __init__.py # Exports MyComputeFramework │ ├── my_compute_framework.py # MyComputeFramework class │ └── tests/ │ ├── __init__.py # Empty test module │ └── test_my_compute_framework.py └── extenders/ ├── __init__.py # Contains: """Extenders namespace package.""" └── my_plugin/ ├── __init__.py # Exports MyExtender ├── my_extender.py # MyExtender class └── tests/ ├── __init__.py # Empty test module └── test_my_extender.py ``` -------------------------------- ### Run Full Check Suite Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/CONTRIBUTING.md Execute the complete suite of checks using tox to verify your local development setup. ```bash tox ``` -------------------------------- ### Run Customization Script Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Re-run the customization script if import errors persist after initial setup. Replace '' with your actual package name. ```bash # Run customization script again if needed ./bin/customize.sh ``` -------------------------------- ### ComputeFramework Export Pattern Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md Example of an __init__.py file for exporting a ComputeFramework. This pattern makes the custom ComputeFramework accessible upon package import. ```python # /compute_frameworks/my_plugin/__init__.py from .compute_frameworks.my_plugin.my_compute_framework import MyComputeFramework __all__ = ["MyComputeFramework"] ``` -------------------------------- ### Package Distribution Structure in Site-Packages Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Shows the mirrored structure of the plugin within the site-packages directory after installation. ```tree site-packages/ └── myorg/ ├── feature_groups/ │ └── my_plugin/ ├── compute_frameworks/ │ └── my_plugin/ └── extenders/ └── my_plugin/ ``` -------------------------------- ### Test ComputeFramework Implementation Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Example unit tests for a ComputeFramework, verifying inheritance from `ComputeFramework` and basic instantiation. Includes a placeholder for testing specific modes. ```python from .compute_frameworks. import MyComputeFramework from mloda.provider import ComputeFramework def test_extends_base(): assert issubclass(MyComputeFramework, ComputeFramework) def test_instantiation(): instance = MyComputeFramework() assert instance is not None def test_with_custom_mode(): # Test with specific modes pass ``` -------------------------------- ### Tool Configurations in pyproject.toml Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md Example TOML snippet showing configurations for ruff (line length), mypy (strictness and ignoring missing imports), and bandit (excluding directories). ```toml [tool.ruff] line-length = 120 [tool.mypy] strict = true ignore_missing_imports = true [tool.bandit] exclude_dirs = [".tox", ".venv", "tests"] ``` -------------------------------- ### Development Dependencies Configuration Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/configuration.md Lists development tools such as tox, uv, pytest, ruff, mypy, and bandit for testing, formatting, and analysis. These are installed using `uv sync --all-extras`. ```toml [project.optional-dependencies] dev = [ "tox", "tox-uv", "uv>=0.11.6", "pytest", "ruff", "mypy", "bandit", ] ``` -------------------------------- ### Conventional Commit Examples Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/AGENTS.md Examples of commit messages following the Conventional Commits specification. This format is used for automated versioning and release tooling. ```git fix: handle empty feature set chore(deps): bump mloda to 0.4.6 ``` -------------------------------- ### Check for Placeholders Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/README.md Command to specifically check for any remaining placeholder strings in the plugin configuration after setup. This is enforced by the CI workflow. ```bash tox -e placeholders ``` -------------------------------- ### Activate Virtual Environment Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/CLAUDE.md Activates the project's virtual environment using `uv`. Ensure this is done before installing dependencies or running checks. ```bash source .venv/bin/activate ``` -------------------------------- ### Customization Script Execution Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/OVERVIEW.md The `customize.sh` script automates the initial setup of a new plugin by renaming directories, updating metadata, and rewriting imports. ```bash #!/bin/bash # Exit immediately if a command exits with a non-zero status. set -e # --- Configuration --- # Replace 'placeholder' with your desired package name. # Replace 'My Plugin Name' with your desired plugin name. # Replace 'my-plugin' with your desired PyPI package name. NEW_PACKAGE_NAME="placeholder" NEW_PLUGIN_NAME="my_plugin" NEW_PYPI_NAME="my-plugin" # --- Script Logic --- # Check if customization has already been run if [ ! -d "${NEW_PACKAGE_NAME}" ]; then echo "Customization script has already been run or the directory '${NEW_PACKAGE_NAME}' does not exist." exit 1 fi # 1. Rename placeholder directory echo "Renaming placeholder/ to ${NEW_PACKAGE_NAME}/..." if [ "${NEW_PACKAGE_NAME}" != "placeholder" ]; then mv placeholder "${NEW_PACKAGE_NAME}" fi # 2. Update pyproject.toml echo "Updating pyproject.toml..." sed -i "s/name = \"my-plugin\"/name = \"${NEW_PYPI_NAME}\"/" pyproject.toml sed -i "s/version = \"0.1.0\"/version = \"0.1.0\"/" pyproject.toml # Placeholder for version sed -i "s/description = \"My plugin description\"/description = \"My plugin description\"/" pyproject.toml # Placeholder for description sed -i "s/authors = \[\n \{ name = \"Your Name\", email = \"your.email@example.com\" \}\n\]/authors = [ { name = \"Your Name\", email = \"your.email@example.com\" } ]/" pyproject.toml # Placeholder for authors # 3. Update .releaserc.yaml (if it exists) if [ -f ".releaserc.yaml" ]; then echo "Updating .releaserc.yaml..." sed -i "s/name: my-plugin/name: ${NEW_PYPI_NAME}/" .releaserc.yaml fi # 4. Rewrite imports throughout the codebase echo "Rewriting imports..." find "${NEW_PACKAGE_NAME}" -type f -name "*.py" -exec sed -i "s/from placeholder/from ${NEW_PACKAGE_NAME}/g" {} \; sed -i "s/import placeholder./import ${NEW_PACKAGE_NAME}./g" {} \; sed -i "s/from placeholder./from ${NEW_PACKAGE_NAME}./g" {} \; sed -i "s/placeholder\./${NEW_PACKAGE_NAME}\./g" {} \; # Handle cases where placeholder is used as a module name sed -i "s/import placeholder/import ${NEW_PACKAGE_NAME}/g" {} \; # Handle relative imports that might need adjustment (less common but possible) # This part is more complex and might require manual review depending on the structure # For simplicity, we focus on direct 'placeholder' references. # Example: Adjusting relative imports if placeholder was a top-level package # sed -i "s/from .placeholder/from .${NEW_PACKAGE_NAME}/g" {} \; # sed -i "s/from ..placeholder/from ..${NEW_PACKAGE_NAME}/g" {} \; # etc. # Note: Relative imports within the new package structure should generally remain correct # after renaming the top-level package, unless they explicitly referenced 'placeholder'. # The above sed commands should cover most direct references. # If you encounter issues with relative imports, manual adjustment might be needed. # For example, if you had 'from .feature_groups.placeholder_feature import MyFeature', # and renamed 'placeholder' to 'my_package', it might become 'from .feature_groups.my_feature import MyFeature'. # The current sed commands focus on replacing 'placeholder' as a module/package name. # Replace placeholder plugin names if they are consistent # This is a more advanced step and depends on how placeholders are used within files. # For example, if you have a file named 'placeholder_feature.py' and want to rename it. # This requires more specific pattern matching. # For now, we focus on the package name itself. # Update __init__.py files if they reference placeholder directly if grep -q "__version__ = \"0.1.0\"" {} && grep -q "from placeholder." {} ; then sed -i "s/from placeholder./from ${NEW_PACKAGE_NAME}./g" {} fi # Update tests if they reference placeholder directly if [[ "{}" == tests/* ]]; then sed -i "s/import placeholder/import ${NEW_PACKAGE_NAME}/g" {} sed -i "s/from placeholder/from ${NEW_PACKAGE_NAME}/g" {} fi # Ensure the new package name is used in module-level docstrings or comments if applicable # This is highly context-dependent and usually requires manual review. # Clean up potential empty lines or excessive whitespace introduced by sed (optional) # awk '/./{line("");next} NF' {} > temp && mv temp {} # Ensure the new package name is used in the plugin registration if applicable # This is typically done in __init__.py or specific plugin files. # Example: If you have a line like 'register_plugin(placeholder.feature_groups.my_plugin)' # it should be updated. The current sed commands should handle this if 'placeholder' is used. # Update any references to the placeholder plugin name itself if it's used as a string literal # Example: If you have config like 'plugin_name = "placeholder"' # This is also context-dependent. # Final check for any remaining 'placeholder' strings that are not part of code/imports # This might require more sophisticated tools or manual inspection. # For now, we rely on the above specific replacements. # Ensure the new package name is used in the setup.py or pyproject.toml if not already handled # pyproject.toml is handled above. # Update any example usage or documentation strings within the code that reference 'placeholder' # This is generally a manual task, but simple string replacements can be attempted. # Example: If a docstring contains 'from placeholder.feature_groups import ...' # The sed commands above should catch this. # Example: If a comment contains '# Using placeholder plugin' # This is harder to target reliably with sed without affecting actual code. # Ensure that the new package name is correctly reflected in any internal module paths # For example, if a file was 'placeholder/feature_groups/my_feature.py', # and you renamed 'placeholder' to 'my_package', the path becomes 'my_package/feature_groups/my_feature.py'. # The 'mv' command handles the directory renaming. The sed commands handle import statements. # Special handling for __init__.py files to ensure they correctly expose the package # If __init__.py contains 'from .module import ...', and 'placeholder' was part of that module path, # the sed commands should update it. # Ensure that the package name is correctly used in tests # Tests often import the package directly or indirectly. # The sed commands targeting test files should handle this. # If the template uses a specific convention for plugin registration, ensure that is updated. # For example, if there's a central registry and 'placeholder' is registered. # Final check for any hardcoded strings that might contain 'placeholder' and need replacement. # This is a common source of errors after renaming. # Example: If a configuration file or a string literal in code refers to 'placeholder'. # This is best handled by a more robust find-and-replace tool or manual review. # Ensure that the new package name is used in any generated documentation files (e.g., Sphinx conf.py) # This is outside the scope of this script but important for full customization. # Clean up any temporary files created by sed (e.g., on macOS) find "${NEW_PACKAGE_NAME}" -type f -name "*.py" -exec sed -i '' "s/placeholder/REPLACED_PLACEHOLDER/g" {} \; find "${NEW_PACKAGE_NAME}" -type f -name "*.py" -exec sed -i '' "s/REPLACED_PLACEHOLDER/${NEW_PACKAGE_NAME}/g" {} \; # Remove the placeholder directory if it was renamed if [ -d "placeholder" ] && [ "${NEW_PACKAGE_NAME}" != "placeholder" ]; then rmdir placeholder 2>/dev/null || true fi # Remove the placeholder plugin directory if it was renamed if [ -d "${NEW_PACKAGE_NAME}/my_plugin" ] && [ "${NEW_PLUGIN_NAME}" != "my_plugin" ]; then mv "${NEW_PACKAGE_NAME}/my_plugin" "${NEW_PACKAGE_NAME}/${NEW_PLUGIN_NAME}" fi # Remove the placeholder PyPI name if it was renamed if [ -f "pyproject.toml" ] && grep -q "name = \"my-plugin\"" pyproject.toml && [ "${NEW_PYPI_NAME}" != "my-plugin" ]; then sed -i "s/name = \"my-plugin\"/name = \"${NEW_PYPI_NAME}\"/" pyproject.toml fi # Update README.md if it contains placeholder references if [ -f "README.md" ]; then sed -i "s/placeholder/${NEW_PACKAGE_NAME}/g" README.md sed -i "s/my-plugin/${NEW_PYPI_NAME}/g" README.md fi # Update setup.py if it exists and contains placeholder references if [ -f "setup.py" ]; then sed -i "s/placeholder/${NEW_PACKAGE_NAME}/g" setup.py sed -i "s/my-plugin/${NEW_PYPI_NAME}/g" setup.py fi # Update LICENSE file if it contains placeholder references if [ -f "LICENSE" ]; then sed -i "s/placeholder/${NEW_PACKAGE_NAME}/g" LICENSE fi # Update .github/workflows/test.yml if it contains placeholder references if [ -f ".github/workflows/test.yml" ]; then sed -i "s/placeholder/${NEW_PACKAGE_NAME}/g" .github/workflows/test.yml sed -i "s/my-plugin/${NEW_PYPI_NAME}/g" .github/workflows/test.yml fi # Update tox.ini if it contains placeholder references if [ -f "tox.ini" ]; then sed -i "s/placeholder/${NEW_PACKAGE_NAME}/g" tox.ini sed -i "s/my-plugin/${NEW_PYPI_NAME}/g" tox.ini fi # Update bin/customize.sh itself to reflect the new names (optional, but good practice) # This is tricky as it might break the script if not done carefully. # For simplicity, we'll leave this script as is, assuming it's a one-time run. # Final confirmation message echo "Customization complete!" echo "Package name: ${NEW_PACKAGE_NAME}" echo "Plugin name: ${NEW_PLUGIN_NAME}" echo "PyPI name: ${NEW_PYPI_NAME}" echo "Please review the changes and commit them." exit 0 fi exit 0 ``` -------------------------------- ### FeatureGroup Export Pattern Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md Example of an __init__.py file for exporting a FeatureGroup. Ensures the custom FeatureGroup is available when the package is imported. ```python # /feature_groups/my_plugin/__init__.py from .feature_groups.my_plugin.my_feature_group import MyFeatureGroup __all__ = ["MyFeatureGroup"] ``` -------------------------------- ### Extender Export Pattern Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md Example of an __init__.py file for exporting an Extender. This ensures that custom extenders are properly exposed for use within the MLODA plugin. ```python # /extenders/my_plugin/__init__.py from .extenders.my_plugin.my_extender import MyExtender __all__ = ["MyExtender"] ``` -------------------------------- ### Implement ComputeFramework Class Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Example Python code for implementing a custom ComputeFramework, including initialization logic and handling of parallelization modes. Requires imports from `mloda.provider` and related modules. ```python from typing import Optional, Set from uuid import UUID, uuid4 from mloda.provider import ComputeFramework from mloda.core.abstract_plugins.components.parallelization_modes import ParallelizationMode from mloda.core.abstract_plugins.function_extender import Extender class MyComputeFramework(ComputeFramework): """Description of your compute framework.""" def __init__( self, mode: ParallelizationMode = ParallelizationMode.SYNC, children_if_root: frozenset[UUID] = frozenset(), uuid: UUID = uuid4(), function_extender: Optional[Set[Extender]] = None, ) -> None: """Initialize your framework.""" super().__init__(mode, children_if_root, uuid, function_extender) # Add your initialization logic ``` -------------------------------- ### Calculate Feature Example Usage Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/feature-groups.md Demonstrates how to call the `calculate_feature` class method to compute features. Pass input data and feature specifications. ```python # Using the FeatureGroup to calculate features result = MyFeatureGroup.calculate_feature( data={"input": "value"}, features=["feature1", "feature2"] ) print(result) # {"example": "data"} ``` -------------------------------- ### Integrate Extenders with Compute Framework Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/extenders.md Example of passing a set of extenders to a ComputeFramework. This allows the framework to utilize the custom behavior defined by the extenders during computations. ```python from placeholder.compute_frameworks.my_plugin import MyComputeFramework from placeholder.extenders.my_plugin import MyExtender # Create extenders extenders = {MyExtender()} # Pass to framework for behavior modification framework = MyComputeFramework(function_extender=extenders) ``` -------------------------------- ### Implement FeatureGroup Class Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Example Python code for implementing a custom FeatureGroup, including the `calculate_feature` method. Requires importing `FeatureGroup` from `mloda.provider`. ```python from typing import Any from mloda.provider import FeatureGroup class MyFeatureGroup(FeatureGroup): """Description of your feature group.""" @classmethod def calculate_feature(cls, data: Any, features: Any) -> Any: """Calculate features from data.""" # Your implementation here return computed_features ``` -------------------------------- ### Minimal ComputeFramework Implementation Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md A basic Python class implementing the ComputeFramework interface. This example shows the constructor with default parameters for parallelization mode and UUID generation. ```python from uuid import UUID, uuid4 from typing import Optional, Set from mloda.provider import ComputeFramework from mloda.core.abstract_plugins.components.parallelization_modes import ParallelizationMode from mloda.core.abstract_plugins.function_extender import Extender class MyComputeFramework(ComputeFramework): def __init__( self, mode: ParallelizationMode = ParallelizationMode.SYNC, children_if_root: frozenset[UUID] = frozenset(), uuid: UUID = uuid4(), function_extender: Optional[Set[Extender]] = None, ) -> None: super().__init__(mode, children_if_root, uuid, function_extender) ``` -------------------------------- ### Export Extender Plugin Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/extenders.md Example of exporting a custom Extender class from a plugin's `__init__.py` file. This makes the extender discoverable and loadable by the mloda framework. ```python # placeholder/extenders/my_plugin/__init__.py from placeholder.extenders.my_plugin.my_extender import MyExtender __all__ = ["MyExtender"] ``` -------------------------------- ### Minimal Extender Implementation Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md A basic Python class implementing the Extender interface. This example defines the required `wraps` method and a simple `__call__` method that executes the wrapped function. ```python from typing import Any, Set from mloda.core.abstract_plugins.function_extender import Extender, ExtenderHook class MyExtender(Extender): def wraps(self) -> Set[ExtenderHook]: return set() def __call__(self, func: Any, *args: Any, **kwargs: Any) -> Any: return func(*args, **kwargs) ``` -------------------------------- ### Configure Build System with setuptools Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/configuration.md Specifies setuptools as the build backend for the package. This is defined in the [build-system] section of the configuration. ```toml [build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" ``` -------------------------------- ### Conventional Commit Message Examples Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Adhere to the Conventional Commits specification for commit messages. Examples cover various types like `feat`, `fix`, `chore`, `docs`, `test`, and `refactor`. ```git feat: add support for distributed computing fix: handle empty feature set edge case chore(deps): update mloda to 0.7.1 docs: clarify feature group interface test: add integration tests for parallel execution refactor: simplify compute framework initialization ``` -------------------------------- ### Package Discovery Configuration Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/configuration.md Configures how setuptools discovers your plugin's packages. The `include` pattern should be customized after renaming the package. ```toml [tool.setuptools.packages.find] where = [". ``` ```toml include = ["placeholder*"] ``` -------------------------------- ### Plugin Package Init File with Exports Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Demonstrates how a plugin's __init__.py file exports its public classes using the __all__ variable. ```python # placeholder/feature_groups/my_plugin/__init__.py """My Plugin FeatureGroup package.""" from placeholder.feature_groups.my_plugin.my_feature_group import MyFeatureGroup __all__ = ["MyFeatureGroup"] ``` -------------------------------- ### Create a Feature Branch Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/CONTRIBUTING.md Create a new branch for your feature or fix, starting from the main branch. ```bash git checkout -b fix/short-description ``` -------------------------------- ### Initialize MyComputeFramework with Default Settings Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/compute-frameworks.md Instantiate MyComputeFramework using default values, including synchronous parallelization mode. ```python from placeholder.compute_frameworks.my_plugin import MyComputeFramework from mloda.core.abstract_plugins.components.parallelization_modes import ParallelizationMode from uuid import UUID, uuid4 # Create with default synchronous mode framework = MyComputeFramework() ``` -------------------------------- ### Root Package Init File Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Shows the typical content of the root package's __init__.py file, which is often empty. ```python # Empty or minimal content ``` -------------------------------- ### Equivalent Import Statements Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Demonstrates that both package-level and direct implementation file imports work, but package-level imports are preferred for consistency. ```python # These are equivalent (both work) from placeholder.feature_groups.my_plugin import MyFeatureGroup from placeholder.feature_groups.my_plugin.my_feature_group import MyFeatureGroup # But prefer the first for consistency ``` -------------------------------- ### Import ComputeFramework Class Directly Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Demonstrates how to import a specific ComputeFramework class directly from its implementation file. ```python from placeholder.compute_frameworks.my_plugin.my_compute_framework import MyComputeFramework ``` -------------------------------- ### Test Feature Calculation with Fixture Data Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/testing-guide.md An example test case that utilizes the `sample_data` fixture to test the `calculate_feature` method of a `SalesFeatureGroup`. ```python def test_feature_calculation(sample_data: Dict[str, Any]) -> None: """Test with fixture data.""" from .feature_groups.sales import SalesFeatureGroup result = SalesFeatureGroup.calculate_feature(sample_data, ["total"]) assert result["total"] == 600 ``` -------------------------------- ### Test Isolation Example Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/testing-guide.md Write independent tests that do not rely on the execution order or state from other tests. This ensures reliability and easier debugging. ```python # Good: Each test is self-contained def test_feature_1() -> None: result = calculate(data1) assert result == expected1 def test_feature_2() -> None: result = calculate(data2) assert result == expected2 # Avoid: Tests relying on execution order def test_setup() -> None: global shared_state shared_state = initialize() def test_use_state() -> None: # Depends on test_setup running first assert shared_state is not None ``` -------------------------------- ### Pytest Fixture for Sample Data Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/testing-guide.md Defines a pytest fixture to provide sample data for tests, demonstrating setup and teardown patterns. ```python import pytest from typing import Any, Dict @pytest.fixture def sample_data() -> Dict[str, Any]: """Provide sample data for tests.""" return { "customer_id": 123, "transactions": [100, 200, 300], "status": "active" } ``` -------------------------------- ### Compute Framework Package Initialization Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/compute-frameworks.md The __init__.py file exports the custom ComputeFramework class, allowing the mloda framework to discover and load it. ```python from placeholder.compute_frameworks.my_plugin.my_compute_framework import MyComputeFramework __all__ = ["MyComputeFramework"] ``` -------------------------------- ### Import Paths for Multi-Plugin Organization Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Shows how to import plugins when multiple plugins of the same type are organized as siblings. ```python from placeholder.feature_groups.sales_features import SalesFeatureGroup from placeholder.feature_groups.customer_features import CustomerFeatureGroup ``` -------------------------------- ### Define a Custom Extender Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/extenders.md Example of defining a custom Extender by inheriting from the base Extender class. Rename and customize this for your specific use case. ```python class MyExtender(Extender): """Example Extender - rename and customize for your use case.""" ``` -------------------------------- ### Integrate Extenders with ComputeFramework Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/compute-frameworks.md Demonstrates how to create a ComputeFramework and attach custom extenders for behavior modification during computation. ```python from placeholder.compute_frameworks.my_plugin import MyComputeFramework from placeholder.extenders.my_plugin import MyExtender # Create framework with extenders extenders = {MyExtender()} framework = MyComputeFramework(function_extender=extenders) # The framework will use the extenders to modify function behavior # during computation execution ``` -------------------------------- ### Create ComputeFramework File Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Command to create a new Python file for a ComputeFramework within the plugin structure. ```bash touch /compute_frameworks//.py ``` -------------------------------- ### Initialize MyComputeFramework with Function Extenders Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/compute-frameworks.md Instantiate MyComputeFramework and attach custom function extenders to modify computation behavior. ```python from placeholder.compute_frameworks.my_plugin import MyComputeFramework from mloda.core.abstract_plugins.components.parallelization_modes import ParallelizationMode from uuid import UUID, uuid4 # Create with function extenders from placeholder.extenders.my_plugin import MyExtender extenders = {MyExtender()} framework = MyComputeFramework( function_extender=extenders ) ``` -------------------------------- ### Verbose Pytest Output Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/testing-guide.md Use the `-v` flag with `pytest` to get more detailed output during test execution, showing each test's status. ```bash pytest -v ``` -------------------------------- ### Create Extender File Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Use this command to create the Python file for your new extender. ```bash touch /extenders//.py ``` -------------------------------- ### Import MyComputeFramework Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/compute-frameworks.md Import the MyComputeFramework class from its plugin location. ```python from placeholder.compute_frameworks.my_plugin import MyComputeFramework ``` -------------------------------- ### Mocking External API Calls Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/testing-guide.md Use `unittest.mock.patch` to isolate external dependencies like API calls during testing. This example mocks `requests.get` to control its response. ```python from unittest.mock import Mock, patch import pytest def test_feature_with_mocked_api() -> None: """Test feature calculation with mocked API.""" from .feature_groups.external import ExternalFeatureGroup with patch('requests.get') as mock_get: mock_get.return_value.json.return_value = {"status": "success"} result = ExternalFeatureGroup.calculate_feature({}, ["status"]) assert result["status"] == "success" mock_get.assert_called_once() ``` -------------------------------- ### Search for Placeholder Imports Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Scan your project for any remaining 'from placeholder.' imports. These indicate parts of the customization that may not have been fully updated. ```bash # Search for remaining placeholder imports grep -r "from placeholder\." . ``` -------------------------------- ### Initialize MyComputeFramework with Custom UUID and Root Children Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/compute-frameworks.md Instantiate MyComputeFramework with a specific UUID and a set of child execution IDs for root operation. ```python from placeholder.compute_frameworks.my_plugin import MyComputeFramework from mloda.core.abstract_plugins.components.parallelization_modes import ParallelizationMode from uuid import UUID, uuid4 # Create with custom UUID and root children framework = MyComputeFramework( uuid=uuid4(), children_if_root=frozenset([UUID("12345678-1234-5678-1234-567812345678")]) ) ``` -------------------------------- ### Implement Extender Class Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Define a custom extender by inheriting from `Extender` and implementing the `wraps` and `__call__` methods. This example shows an extender that wraps the `COMPUTE` hook. ```python from typing import Any, Set from mloda.core.abstract_plugins.function_extender import Extender, ExtenderHook class MyExtender(Extender): """Description of your extender.""" def wraps(self) -> Set[ExtenderHook]: """Return which hooks this extender wraps.""" return {ExtenderHook.COMPUTE} # Or your hooks def __call__(self, func: Any, *args: Any, **kwargs: Any) -> Any: """Wrap and potentially modify function behavior.""" # Pre-processing print(f"Calling {func.__name__}") # Call the function result = func(*args, **kwargs) # Post-processing return result ``` -------------------------------- ### Import Extender Class Directly Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Demonstrates how to import a specific Extender class directly from its implementation file. ```python from placeholder.extenders.my_plugin.my_extender import MyExtender ``` -------------------------------- ### Minimal FeatureGroup Implementation Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md A basic Python class implementing the FeatureGroup interface. This serves as a starting point for defining custom feature groups in your MLODA plugin. ```python from typing import Any from mloda.provider import FeatureGroup class MyFeatureGroup(FeatureGroup): @classmethod def calculate_feature(cls, data: Any, features: Any) -> Any: return {"result": "value"} ``` -------------------------------- ### Clone the Repository Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/CONTRIBUTING.md Clone your forked repository to your local machine and navigate into the project directory. ```bash git clone https://github.com//mloda-plugin-template.git cd mloda-plugin-template ``` -------------------------------- ### Define custom plugin environment variables Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/configuration.md Example of how to define and retrieve custom environment variables within a Python plugin. It demonstrates setting default values if the variables are not found. ```python import os API_KEY = os.getenv("MY_PLUGIN_API_API_KEY", default="") TIMEOUT = int(os.getenv("MY_PLUGIN_TIMEOUT", default="30")) ``` -------------------------------- ### MyComputeFramework Constructor Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/compute-frameworks.md Initializes a `MyComputeFramework` instance, allowing configuration of parallelization mode, root children, unique identifier, and function extenders. ```APIDOC ## MyComputeFramework Constructor ### Description Initializes a ComputeFramework with parallelization settings and optional extensions. ### Signature ```python def __init__( self, mode: ParallelizationMode = ParallelizationMode.SYNC, children_if_root: frozenset[UUID] = frozenset(), uuid: UUID = uuid4(), function_extender: Optional[Set[Extender]] = None, ) -> None: """Initialize with default values for minimal instantiation.""" ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **mode** (ParallelizationMode) - Optional - Execution mode (SYNC for synchronous, or other modes). Defaults to `ParallelizationMode.SYNC`. - **children_if_root** (frozenset[UUID]) - Optional - Child execution IDs if this is the root framework. Defaults to `frozenset()`. - **uuid** (UUID) - Optional - Unique identifier for this framework instance. Defaults to `uuid4()`. - **function_extender** (Optional[Set[Extender]]) - Optional - Set of Extender instances for behavior modification. Defaults to `None`. ### Request Example ```python from placeholder.compute_frameworks.my_plugin import MyComputeFramework from mloda.core.abstract_plugins.components.parallelization_modes import ParallelizationMode from uuid import UUID, uuid4 # Create with default synchronous mode framework = MyComputeFramework() # Create with custom parallelization mode framework = MyComputeFramework( mode=ParallelizationMode.SYNC ) # Create with custom UUID and root children framework = MyComputeFramework( uuid=uuid4(), children_if_root=frozenset([UUID("12345678-1234-5678-1234-567812345678")]) ) # Create with function extenders from placeholder.extenders.my_plugin import MyExtender extenders = {MyExtender()} framework = MyComputeFramework( function_extender=extenders ) ``` ### Response #### Success Response (200) None #### Response Example None ### Throws - May raise exceptions if invalid parameters are provided (validation depends on base class implementation) ``` -------------------------------- ### Publishing Plugin to PyPI Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Commands to build and publish your plugin package using `uv`. Ensure your version is updated in `pyproject.toml` or managed by `semantic-release`. ```bash uv build uv publish ``` -------------------------------- ### MyExtender.__init__ Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/extenders.md Initializes the MyExtender. It uses the default constructor inherited from the base Extender class, requiring no specific arguments. ```APIDOC ## MyExtender.__init__ ### Description Initializes the MyExtender. It uses the default constructor inherited from the base Extender class, requiring no specific arguments. ### Signature ```python def __init__(self) -> None: ``` ### Example ```python from placeholder.extenders.my_plugin import MyExtender # Create an extender instance extender = MyExtender() ``` ``` -------------------------------- ### Call Wrapped Function with Extender Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/extenders.md Execute a function through an extender instance. The extender's `__call__` method wraps the function execution, allowing for modifications. This example demonstrates calling a function with positional and keyword arguments. ```python from placeholder.extenders.my_plugin import MyExtender extender = MyExtender() # Define a function to wrap def add(a, b): return a + b # Call the function through the extender result = extender(add, 2, 3) print(result) # 5 # With keyword arguments def greet(name, greeting="Hello"): return f"{greeting}, {name}!" result = extender(greet, "Alice", greeting="Hi") print(result) ``` -------------------------------- ### Extended FeatureGroup Test Example Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/testing-guide.md Test a FeatureGroup's calculate_feature method with various inputs, including valid data, empty data, and invalid feature requests. This ensures robustness and correct handling of edge cases. ```python from .feature_groups.sales import SalesFeatureGroup from mloda.provider import FeatureGroup import pytest def test_extends_base() -> None: assert issubclass(SalesFeatureGroup, FeatureGroup) def test_calculate_feature_with_data() -> None: data = {"customer_id": 123, "transactions": [100, 200, 300]} features = ["total_spend", "transaction_count"] result = SalesFeatureGroup.calculate_feature(data, features) assert "total_spend" in result assert result["total_spend"] == 600 assert "transaction_count" in result assert result["transaction_count"] == 3 def test_calculate_feature_empty_data() -> None: result = SalesFeatureGroup.calculate_feature({}, []) assert isinstance(result, dict) def test_calculate_feature_invalid_feature() -> None: with pytest.raises(KeyError): SalesFeatureGroup.calculate_feature( {"id": 1}, ["nonexistent_feature"] ) ``` -------------------------------- ### Development Commands for Testing, Formatting, Linting, and Type Checking Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md Essential commands for local development, including running tests with pytest, formatting and checking code with ruff, linting with ruff, and type checking with mypy. Also includes a security scan with bandit and a comprehensive check with tox. ```bash # Run tests pytest # Format code ruff format --line-length 120 . # Check formatting ruff format --check --line-length 120 . # Lint code ruff check . # Type check mypy --strict --ignore-missing-imports . # Security scan bandit -c pyproject.toml -r -q . # All checks tox ``` -------------------------------- ### Modern Python Type Hint Syntax Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Utilize modern Python 3.10+ type hinting for improved code clarity and maintainability. This example shows correct usage of `list[str]`, `dict[str, int]`, and `str | None`. ```python # Correct def process(items: list[str], config: dict[str, int]) -> str | None: pass # Avoid (outdated) from typing import List, Dict, Optional def process(items: List[str], config: Dict[str, int]) -> Optional[str]: pass ``` -------------------------------- ### Import ComputeFramework in Tests Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Illustrates imports for ComputeFramework within a test environment, including the base ComputeFramework class. ```python from placeholder.compute_frameworks.my_plugin import MyComputeFramework from mloda.provider import ComputeFramework ``` -------------------------------- ### Initialize MyComputeFramework with Custom Parallelization Mode Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/compute-frameworks.md Instantiate MyComputeFramework specifying a custom parallelization mode, such as synchronous. ```python from placeholder.compute_frameworks.my_plugin import MyComputeFramework from mloda.core.abstract_plugins.components.parallelization_modes import ParallelizationMode from uuid import UUID, uuid4 # Create with custom parallelization mode framework = MyComputeFramework( mode=ParallelizationMode.SYNC ) ``` -------------------------------- ### Project Metadata Configuration Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/configuration.md Defines the core metadata for your plugin package, including name, version, description, license, authors, and Python version requirements. ```toml [project] name = "myorg-my-plugin" version = "0.3.4" description = "My custom mloda plugin" license = "Apache-2.0" authors = [{name = "Jane Doe", email = "jane@myorg.com"}] requires-python = ">=3.10" ``` -------------------------------- ### Import FeatureGroup Class Directly Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/module-structure.md Demonstrates how to import a specific FeatureGroup class directly from its implementation file. ```python from placeholder.feature_groups.my_plugin.my_feature_group import MyFeatureGroup ``` -------------------------------- ### Running All Quality Checks with Tox Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/testing-guide.md Execute `tox` to run a comprehensive suite of quality checks, including tests, formatting, linting, type checking, and security analysis. ```bash # This is what you must do before committing tox # It runs: # - pytest (tests) # - ruff format --check (formatting) # - ruff check (linting) # - mypy --strict (type checking) # - bandit (security) ``` -------------------------------- ### Compute Framework Implementation Pattern Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/api-reference/compute-frameworks.md This pattern outlines the steps for creating a custom ComputeFramework, emphasizing inheritance, initialization, and extensibility. ```python # 1. Extend ComputeFramework from mloda.provider import ComputeFramework class MyComputeFramework(ComputeFramework): # 2. Customize __init__ def __init__(self, framework_params=None, extenders=None): # 3. Call super().__init__() super().__init__(extenders=extenders) self.framework_params = framework_params or {} # 4. Add framework-specific logic # ... # 5. Support extenders (handled by base class if passed during init) # ... # 7. Export from __init__.py (see first snippet) ``` -------------------------------- ### Creating New Component Files Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/quick-reference.md Commands to create the basic file structure for new FeatureGroup, ComputeFramework, and Extender components within your MLODA plugin. ```bash # New FeatureGroup file touch /feature_groups//.py # New ComputeFramework file touch /compute_frameworks//.py # New Extender file touch /extenders//.py ``` -------------------------------- ### List Test Files Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Check that your test files follow the expected naming convention (e.g., test_*.py). This command lists files matching the pattern in all subdirectories. ```bash # Check that test files match pattern ls -la **/test_*.py ``` -------------------------------- ### Export Extender in __init__.py Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Make your custom extender discoverable by exporting it from your package's `__init__.py` file. ```python from .extenders.. import MyExtender __all__ = ["MyExtender"] ``` -------------------------------- ### Running Ruff Formatter and Linter Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/development-guide.md Employ `ruff` for code formatting and linting. Commands are provided to format code, check formatting compliance, lint for issues, and automatically fix fixable problems. ```bash # Format code (line length 120) ruff format --line-length 120 . # Check formatting ruff format --check --line-length 120 . # Lint code ruff check . # Fix auto-fixable issues ruff check --fix . ``` -------------------------------- ### Runtime Dependencies Configuration Source: https://github.com/mloda-ai/mloda-plugin-template/blob/main/_autodocs/configuration.md Specifies the core mloda framework and testing utilities required for your plugin to run. These are minimum versions for compatibility. ```toml dependencies = ["mloda>=0.7.0", "mloda-testing>=0.3.2"] ```