Skip to main content

App4 Plugin SDK for Python

Python SDK for building App4 plugins that integrate with the App4 platform via gRPC.

Installation

pip install app4-sdk

For development:

pip install app4-sdk[dev]

Quick Start

1. Create a Plugin

from app4_sdk import (
    Plugin,
    Manifest,
    ActionMeta,
    ParamSchema,
    Context,
    serve,
)

class MyPlugin(Plugin):
    def manifest(self) -> Manifest:
        return Manifest(
            name="my-plugin",
            version="1.0.0",
            description="My awesome plugin",
            capabilities=["actions"],
        )

    def list_actions(self) -> list[ActionMeta]:
        return [
            ActionMeta(
                name="my-plugin:greet",
                description="Say hello",
                inputs={
                    "name": ParamSchema(
                        name="name",
                        type="string",
                        required=True,
                        description="Name to greet",
                    ),
                },
                outputs={
                    "message": ParamSchema(
                        name="message",
                        type="string",
                        description="Greeting message",
                    ),
                },
            ),
        ]

    def execute_action(
        self,
        ctx: Context,
        action_name: str,
        data: dict,
        config: dict,
    ) -> dict:
        if action_name == "my-plugin:greet":
            name = data.get("name", "World")
            ctx.info(f"Greeting {name}")
            return {"message": f"Hello, {name}!"}

        raise ValueError(f"Unknown action: {action_name}")

if __name__ == "__main__":
    serve(MyPlugin(), ":50051")

2. Run the Plugin

python my_plugin.py

3. With Registry Integration

from app4_sdk import serve_with_registry, RegistryConfig

config = RegistryConfig(
    address="localhost:50100",
    heartbeat_seconds=10,
)

serve_with_registry(MyPlugin(), ":50051", config)

Or use environment variables:

export PLUGIN_REGISTRY_ADDRESS=localhost:50100
python my_plugin.py --registry

Features

Action Metadata

Define rich metadata for your actions:

ActionMeta(
    name="mongo:find",
    category="database",
    description="Find documents in a collection",
    tags=["mongodb", "query", "read"],
    inputs={
        "collection": ParamSchema(
            name="collection",
            type="string",
            required=True,
            ui_component="TextInput",
        ),
        "filter": ParamSchema(
            name="filter",
            type="object",
            required=False,
            default={},
            ui_component="JsonEditor",
        ),
    },
    outputs={
        "documents": ParamSchema(
            name="documents",
            type="array",
            description="Found documents",
        ),
    },
    examples=[
        ActionExample(
            name="Find all users",
            input={"collection": "users", "filter": {}},
            output={"documents": [{"_id": "1", "name": "Alice"}]},
        ),
    ],
)

Provider Management

Initialize and manage provider connections:

class MyPlugin(Plugin):
    def __init__(self):
        self._connections: dict[str, Any] = {}

    def init_provider(self, name: str, config: dict) -> None:
        # Create connection
        uri = config.get("uri", "localhost:27017")
        self._connections[name] = create_connection(uri)

    def close_provider(self, name: str) -> None:
        # Close connection
        if name in self._connections:
            self._connections[name].close()
            del self._connections[name]

Context and Logging

Use the context for logging and variable access:

def execute_action(self, ctx: Context, action_name: str, data: dict, config: dict):
    ctx.debug("Processing request")
    ctx.info(f"Action: {action_name}")

    # Access input arguments
    user_id = ctx.arg("userId")

    # Access/set context variables
    session = ctx.ctx("session")
    ctx.set_ctx("lastAction", action_name)

    # Set return values
    ctx.set_return("success", True)

    return {"result": "done"}

Health Checks

Implement custom health checking:

def health_check(self) -> tuple[bool, str, dict[str, str]]:
    # Check all connections
    all_healthy = all(
        conn.is_connected() for conn in self._connections.values()
    )

    return (
        all_healthy,
        "OK" if all_healthy else "Some connections unhealthy",
        {
            "connections": str(len(self._connections)),
            "healthy": str(sum(1 for c in self._connections.values() if c.is_connected())),
        },
    )

Export Metadata

Export plugin metadata for documentation:

# Export action metadata as JSON
python my_plugin.py --export-meta

# Export analyzer rules as JSON
python my_plugin.py --export-rules

# Export as Markdown documentation
python my_plugin.py --export-md

Helper Functions

The SDK provides utility functions for config extraction:

from app4_sdk import (
    get_config_string,
    get_config_bool,
    get_config_int,
    get_config_float,
    get_config_list,
    get_config_dict,
    require_config,
    get_nested_value,
    set_nested_value,
)

# Type-safe config extraction
uri = get_config_string(config, "uri", "localhost:27017")
timeout = get_config_int(config, "timeout", 30)
ssl = get_config_bool(config, "ssl", False)

# Require specific keys
require_config(config, "uri", "database")  # Raises ValueError if missing

# Nested value access
name = get_nested_value(data, "user.profile.name")
set_nested_value(result, "response.status", "ok")

Analyzer Rules

Define validation rules for the meta-model analyzer:

def analyzer_rules(self) -> AnalyzerRules:
    return AnalyzerRules(
        plugin_name="mongo",
        plugin_version="1.0.0",
        action_prefix="mongo:",
        provider_type="mongo",
        write_actions=["mongo:insert", "mongo:update", "mongo:delete"],
        read_actions=["mongo:find", "mongo:findOne", "mongo:count"],
        transaction_action="mongo:transaction",
        collection_actions=["mongo:find", "mongo:insert", "mongo:update"],
        collection_field="collection",
    )

Development

Generate Proto Files

make proto

Run Tests

make test

Format Code

make format

API Reference

Types

  • Manifest - Plugin identity and capabilities
  • ActionMeta - Action metadata with inputs/outputs
  • ParamSchema - Parameter schema for inputs/outputs
  • ParamOption - Option for select-type parameters
  • ActionExample - Example usage for an action
  • AnalyzerRules - Validation rules for analyzer
  • PluginStatus - Detailed plugin status
  • PluginResource - Resource tracked by plugin
  • PluginStats - Execution statistics

Interfaces

  • Plugin - Abstract base class for plugins
  • Context - Execution context interface

Functions

  • serve(plugin, address) - Start gRPC server
  • serve_with_registry(plugin, address, config) - Serve with registry
  • serve_with_auto_registry(plugin, address) - Auto-configure registry

Registry

  • RegistryClient - Client for plugin registry
  • RegistryConfig - Registry configuration
  • ConfigClient - Provider config management

License

MIT License - see LICENSE file for details.

Metadata

Release files for app4-sdk 1.1.0

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

Source distribution (sdist)

Source distribution for app4-sdk 1.1.0
File Size Uploaded
app4_sdk-1.1.0.tar.gz 38.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for app4-sdk 1.1.0
File Interpreter ABI Platform
app4_sdk-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 79.2 kB

Release files / app4_sdk-1.1.0.tar.gz

Download URL app4_sdk-1.1.0.tar.gz
Size 38.0 kB
Tags Source
SHA-256 checksum
How to use checksums
66f9e19d72aaca66e3e5a6374197b3a701ae219fcf6d1f2d537fa28ff9ba8bd7
BLAKE2b-256 checksum
How to use checksums
33498165edd8c6bc9e91709e5fc7872c2f704d00a6bd6e1570fe17da0006c124
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / app4_sdk-1.1.0-py3-none-any.whl

Download URL app4_sdk-1.1.0-py3-none-any.whl
Size 41.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fcb07dee2061b32d0dd91eeceda016c50cc4f047525363578852eda0311970d5
BLAKE2b-256 checksum
How to use checksums
89e6bb6599da36b215c9abf0397d75257d0a17a7bebf4c4ba9bc0f576e9e4004
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release history Release notifications | RSS feed

This release

1.1.0 This release

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