Add .env.example with configuration for database, Redis, security, SMTP, workers, and plugins. Add .gitignore for Python, Node.js, Next.js, Docker volumes, and IDE files. Add MIT License. Update README.md with feature overview, quick start guide, architecture description, plugin system documentation, security details, backup/restore instructions, and developer setup. Add Alembic configuration files and placeholder directories for API, web, worker, and plugin components
69 lines
1.9 KiB
Python
69 lines
1.9 KiB
Python
import uuid
|
|
from abc import ABC, abstractmethod
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
from apps.api.src.models.plugin_instance import PluginInstance
|
|
from apps.api.src.models.service_connection import ServiceConnection
|
|
from apps.api.src.security.encryption import decrypt_dict
|
|
from apps.api.src.services import secret_service
|
|
|
|
|
|
class PluginContext:
|
|
def __init__(
|
|
self,
|
|
instance: PluginInstance,
|
|
connection: ServiceConnection | None,
|
|
credentials: dict[str, Any] | None,
|
|
http_client: httpx.AsyncClient,
|
|
):
|
|
self.instance = instance
|
|
self.connection = connection
|
|
self.credentials = credentials or {}
|
|
self.http_client = http_client
|
|
|
|
|
|
class PluginConnector(ABC):
|
|
id: str = ""
|
|
name: str = ""
|
|
default_timeout: float = 30.0
|
|
|
|
def __init__(self, context: PluginContext):
|
|
self.context = context
|
|
|
|
async def get_credentials(self) -> dict[str, Any]:
|
|
return self.context.credentials
|
|
|
|
def get_client(self) -> httpx.AsyncClient:
|
|
return self.context.http_client
|
|
|
|
@abstractmethod
|
|
async def healthcheck(self) -> dict[str, Any]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def fetch_widget_data(self, widget_type: str, settings: dict[str, Any]) -> dict[str, Any]:
|
|
pass
|
|
|
|
async def close(self) -> None:
|
|
pass
|
|
|
|
|
|
async def build_context(
|
|
db,
|
|
instance: PluginInstance,
|
|
) -> PluginContext:
|
|
connection = instance.service_connection
|
|
credentials = None
|
|
if connection and connection.credentials_id:
|
|
secret_value = await secret_service.decrypt_secret_value(db, connection.credentials_id)
|
|
credentials = decrypt_dict(secret_value)
|
|
|
|
client = httpx.AsyncClient(
|
|
verify=connection.verify_tls if connection else True,
|
|
timeout=connection.timeout_seconds if connection else 30,
|
|
follow_redirects=False,
|
|
)
|
|
return PluginContext(instance, connection, credentials, client)
|