Skip to main content

Plugin Types Explained

warning

This language version of the document is translated by DeepSeek AI. For any questions, please refer to the original Chinese version of the document.

WaveYo-API supports various types of plugins, each with specific purposes and development specifications.

1. API Endpoint Plugins

Purpose

Provide RESTful API endpoints to handle HTTP requests and responses.

File Structure

plugins/
└── yoapi_plugin_demoapi/
├── __init__.py # Main file, must contain register function
├── plugin.json # Plugin metadata file
├── requirements.txt # Plugin dependencies
├── .env # Plugin environment variables (optional)
└── routers/ # Sub-routers (optional)
└── v1.py

Code Example

# plugins/yoapi_plugin_demoapi/__init__.py
from fastapi import APIRouter, Depends, HTTPException, status
from plugins.log import get_log_service

router = APIRouter(prefix="/api", tags=["demo-api"])

@router.get("/items")
async def get_items():
"""Get item list"""
return {"items": ["item1", "item2", "item3"]}

@router.get("/items/{item_id}")
async def get_item(item_id: int):
"""Get item details by ID"""
if item_id > 100:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found"
)
return {"item_id": item_id, "name": f"Item {item_id}"}

@router.post("/items")
async def create_item(name: str):
"""Create new item"""
return {"message": f"Item '{name}' created", "id": 123}

def register(app, **dependencies):
# Get logging service
log_service = dependencies.get('log_service')
logger = log_service.get_logger(__name__)

app.include_router(router)
logger.info("API endpoint plugin registered")
logger.debug(f"Registered routes: {[route.path for route in router.routes]}")

2. Database Service Plugins

Purpose

Provide database connections and CRUD operation services.

File Structure

plugins/
└── yoapi_plugin_demodb/
├── __init__.py
├── plugin.json # Plugin metadata file
├── requirements.txt
├── .env
├── models.py # Data models
└── services.py # Service classes

Code Example

# plugins/yoapi_plugin_demodb/__init__.py
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from core.env_validator import get_env_validator, EnvVarType

class DatabaseService:
def __init__(self, db_url: str):
self.engine = create_async_engine(db_url, echo=True)
self.async_session = sessionmaker(
self.engine, class_=AsyncSession, expire_on_commit=False
)

async def get_session(self):
"""Get database session"""
async with self.async_session() as session:
yield session

def register(app, **dependencies):
# Use environment variable validation framework
validator = get_env_validator()
env_schema = {
"DB_URL": {
"type": EnvVarType.STRING,
"required": True,
"description": "Database connection URL"
},
"MAX_CONNECTIONS": {
"type": EnvVarType.INTEGER,
"required": False,
"default": 10,
"min": 1,
"max": 100,
"description": "Maximum connections"
}
}

try:
env_vars = validator.validate_env_vars("demodb", env_schema)
db_url = env_vars["DB_URL"]
max_connections = env_vars["MAX_CONNECTIONS"]
except ValueError as e:
log_service = dependencies.get('log_service')
logger = log_service.get_logger(__name__)
logger.error(f"Environment variable validation failed: {e}")
raise

# Create database service
db_service = DatabaseService(db_url)
dependencies['db_service'] = db_service

logger = dependencies.get('log_service').get_logger(__name__)
logger.info(f"Database service plugin loaded, max connections: {max_connections}")

3. Authentication & Authorization Plugins

Purpose

Provide non-intrusive security controls and permission management.

File Structure

plugins/
└── yoapi_plugin_demoauth/
├── __init__.py
├── plugin.json # Plugin metadata file
├── requirements.txt
├── .env
├── middleware.py # Authentication middleware
└── services.py # Authentication services

Code Example

# plugins/yoapi_plugin_demoauth/__init__.py
from fastapi import Depends, HTTPException, status
from fastapi.security import APIKeyHeader
from core.env_validator import get_env_validator, EnvVarType

api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)

async def api_key_auth(api_key: str = Depends(api_key_header)):
"""API key authentication"""
if not api_key:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="API key missing"
)

# Use environment variable validation framework
validator = get_env_validator()
env_schema = {
"VALID_API_KEY": {
"type": EnvVarType.STRING,
"required": True,
"description": "Valid API key"
}
}

try:
env_vars = validator.validate_env_vars("demoauth", env_schema)
valid_api_key = env_vars["VALID_API_KEY"]
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Server configuration error"
)

if api_key != valid_api_key:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid API key"
)

return api_key

def register(app, **dependencies):
log_service = dependencies.get('log_service')
logger = log_service.get_logger(__name__)

# Add dependency to routes requiring authentication
exempt_paths = ['/health', '/docs', '/openapi.json', '/']

for route in app.routes:
if (hasattr(route, 'path') and
hasattr(route, 'dependencies') and
not any(exempt_path in route.path for exempt_path in exempt_paths)):
route.dependencies.insert(0, Depends(api_key_auth))

logger.info("Authentication plugin loaded, authentication added to protected routes")

4. Utility Plugins

Purpose

Provide general utility functions and auxiliary services.

File Structure

plugins/
└── yoapi_plugin_utils/
├── __init__.py
├── plugin.json # Plugin metadata file
├── requirements.txt
├── .env
└── tools.py # Utility functions

Code Example

# plugins/yoapi_plugin_utils/__init__.py
import hashlib
import json
from datetime import datetime, timedelta
from typing import Any, Dict

class UtilityService:
def __init__(self):
self.cache: Dict[str, Any] = {}

def generate_hash(self, data: str) -> str:
"""Generate SHA256 hash"""
return hashlib.sha256(data.encode()).hexdigest()

def json_serializer(self, obj: Any) -> str:
"""JSON serializer utility"""
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")

def cache_get(self, key: str, default: Any = None) -> Any:
"""Get data from cache"""
return self.cache.get(key, default)

def cache_set(self, key: str, value: Any, ttl: int = 300) -> None:
"""Set cached data"""
self.cache[key] = {
'value': value,
'expires': datetime.now() + timedelta(seconds=ttl)
}

def register(app, **dependencies):
utility_service = UtilityService()
dependencies['utility_service'] = utility_service

logger = dependencies.get('log_service').get_logger(__name__)
logger.info("Utility service plugin loaded")

Choosing the Right Plugin Type

Plugin TypeUse CaseComplexityDependencies
API Endpoint PluginsProvide REST APIsLow-MediumMay depend on database, auth services
Database Service PluginsData persistenceMedium-HighDatabase drivers, connection pools
Authentication PluginsSecurity controlMediumMay depend on user services, token services
Utility PluginsGeneral functionalityLowUsually no external dependencies

Choose the appropriate plugin type based on your requirements and follow the corresponding development specifications.