Add project scaffolding and documentation
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
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user