mirror of
https://github.com/johndoe6345789/AutoMetabuilder.git
synced 2026-04-24 13:54:59 +00:00
Add JSON-based route registration system with API handler plugins
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "web_server_json_routes",
|
||||
"version": "1.0.0",
|
||||
"description": "Web server with routes defined in JSON workflow",
|
||||
"main": "workflow.json",
|
||||
"author": "AutoMetabuilder",
|
||||
"metadata": {
|
||||
"label": "Web Server (JSON Routes)",
|
||||
"tags": ["web", "server", "json-routes"],
|
||||
"icon": "web",
|
||||
"category": "templates"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"name": "Web Server with JSON Routes",
|
||||
"active": true,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "configure_logging",
|
||||
"name": "Configure Logging",
|
||||
"type": "backend.configure_logging",
|
||||
"typeVersion": 1,
|
||||
"position": [0, 0],
|
||||
"parameters": {}
|
||||
},
|
||||
{
|
||||
"id": "load_env",
|
||||
"name": "Load Environment",
|
||||
"type": "backend.load_env",
|
||||
"typeVersion": 1,
|
||||
"position": [300, 0],
|
||||
"parameters": {}
|
||||
},
|
||||
{
|
||||
"id": "create_app",
|
||||
"name": "Create Flask App",
|
||||
"type": "web.create_flask_app",
|
||||
"typeVersion": 1,
|
||||
"position": [600, 0],
|
||||
"parameters": {
|
||||
"name": "autometabuilder",
|
||||
"config": {
|
||||
"JSON_SORT_KEYS": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "register_api_routes",
|
||||
"name": "Register API Routes",
|
||||
"type": "web.register_routes",
|
||||
"typeVersion": 1,
|
||||
"position": [900, 0],
|
||||
"parameters": {
|
||||
"blueprint_name": "api",
|
||||
"routes": [
|
||||
{
|
||||
"path": "/api/navigation",
|
||||
"methods": ["GET"],
|
||||
"handler": "web.api_navigation",
|
||||
"handler_type": "plugin"
|
||||
},
|
||||
{
|
||||
"path": "/api/workflow/packages",
|
||||
"methods": ["GET"],
|
||||
"handler": "web.api_workflow_packages",
|
||||
"handler_type": "plugin"
|
||||
},
|
||||
{
|
||||
"path": "/api/workflow/plugins",
|
||||
"methods": ["GET"],
|
||||
"handler": "web.api_workflow_plugins",
|
||||
"handler_type": "plugin"
|
||||
},
|
||||
{
|
||||
"path": "/api/workflow/graph",
|
||||
"methods": ["GET"],
|
||||
"handler": "web.api_workflow_graph",
|
||||
"handler_type": "plugin"
|
||||
},
|
||||
{
|
||||
"path": "/api/translation-options",
|
||||
"methods": ["GET"],
|
||||
"handler": "web.api_translation_options",
|
||||
"handler_type": "plugin"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "start_server",
|
||||
"name": "Start Web Server",
|
||||
"type": "web.start_server",
|
||||
"typeVersion": 1,
|
||||
"position": [1200, 0],
|
||||
"parameters": {
|
||||
"host": "0.0.0.0",
|
||||
"port": 8000,
|
||||
"debug": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Configure Logging": {
|
||||
"main": {
|
||||
"0": [
|
||||
{
|
||||
"node": "Load Environment",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Load Environment": {
|
||||
"main": {
|
||||
"0": [
|
||||
{
|
||||
"node": "Create Flask App",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Create Flask App": {
|
||||
"main": {
|
||||
"0": [
|
||||
{
|
||||
"node": "Register API Routes",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Register API Routes": {
|
||||
"main": {
|
||||
"0": [
|
||||
{
|
||||
"node": "Start Web Server",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,5 +122,11 @@
|
||||
"web.update_translation": "autometabuilder.workflow.plugins.web.web_update_translation.web_update_translation.run",
|
||||
"web.write_messages_dir": "autometabuilder.workflow.plugins.web.web_write_messages_dir.web_write_messages_dir.run",
|
||||
"web.write_prompt": "autometabuilder.workflow.plugins.web.web_write_prompt.web_write_prompt.run",
|
||||
"web.write_workflow": "autometabuilder.workflow.plugins.web.web_write_workflow.web_write_workflow.run"
|
||||
"web.write_workflow": "autometabuilder.workflow.plugins.web.web_write_workflow.web_write_workflow.run",
|
||||
"web.register_routes": "autometabuilder.workflow.plugins.web.web_register_routes.web_register_routes.run",
|
||||
"web.api_navigation": "autometabuilder.workflow.plugins.web.web_api_navigation.web_api_navigation.run",
|
||||
"web.api_workflow_packages": "autometabuilder.workflow.plugins.web.web_api_workflow_packages.web_api_workflow_packages.run",
|
||||
"web.api_workflow_plugins": "autometabuilder.workflow.plugins.web.web_api_workflow_plugins.web_api_workflow_plugins.run",
|
||||
"web.api_workflow_graph": "autometabuilder.workflow.plugins.web.web_api_workflow_graph.web_api_workflow_graph.run",
|
||||
"web.api_translation_options": "autometabuilder.workflow.plugins.web.web_api_translation_options.web_api_translation_options.run"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "web.api_navigation",
|
||||
"version": "1.0.0",
|
||||
"description": "Handle /api/navigation endpoint",
|
||||
"main": "web_api_navigation.py",
|
||||
"author": "AutoMetabuilder",
|
||||
"category": "web"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
"""Workflow plugin: handle /api/navigation endpoint."""
|
||||
|
||||
|
||||
def run(_runtime, _inputs):
|
||||
"""Return navigation items."""
|
||||
from autometabuilder.data import get_navigation_items
|
||||
return {"result": {"navigation": get_navigation_items()}}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "web.api_translation_options",
|
||||
"version": "1.0.0",
|
||||
"description": "Handle /api/translation-options endpoint",
|
||||
"main": "web_api_translation_options.py",
|
||||
"author": "AutoMetabuilder",
|
||||
"category": "web"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
"""Workflow plugin: handle /api/translation-options endpoint."""
|
||||
|
||||
|
||||
def run(_runtime, _inputs):
|
||||
"""Return available translations."""
|
||||
from autometabuilder.data import list_translations
|
||||
translations = list_translations()
|
||||
return {"result": {"translations": translations}}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "web.api_workflow_graph",
|
||||
"version": "1.0.0",
|
||||
"description": "Handle /api/workflow/graph endpoint",
|
||||
"main": "web_api_workflow_graph.py",
|
||||
"author": "AutoMetabuilder",
|
||||
"category": "web"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
"""Workflow plugin: handle /api/workflow/graph endpoint."""
|
||||
|
||||
|
||||
def run(_runtime, _inputs):
|
||||
"""Return workflow graph."""
|
||||
from autometabuilder.workflow.workflow_graph import build_workflow_graph
|
||||
graph = build_workflow_graph()
|
||||
return {"result": graph}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "web.api_workflow_packages",
|
||||
"version": "1.0.0",
|
||||
"description": "Handle /api/workflow/packages endpoint",
|
||||
"main": "web_api_workflow_packages.py",
|
||||
"author": "AutoMetabuilder",
|
||||
"category": "web"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
"""Workflow plugin: handle /api/workflow/packages endpoint."""
|
||||
|
||||
|
||||
def run(_runtime, _inputs):
|
||||
"""Return workflow packages."""
|
||||
from autometabuilder.data import load_workflow_packages, summarize_workflow_packages
|
||||
packages = load_workflow_packages()
|
||||
return {"result": {"packages": summarize_workflow_packages(packages)}}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "web.api_workflow_plugins",
|
||||
"version": "1.0.0",
|
||||
"description": "Handle /api/workflow/plugins endpoint",
|
||||
"main": "web_api_workflow_plugins.py",
|
||||
"author": "AutoMetabuilder",
|
||||
"category": "web"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
"""Workflow plugin: handle /api/workflow/plugins endpoint."""
|
||||
|
||||
|
||||
def run(_runtime, _inputs):
|
||||
"""Return workflow plugins metadata."""
|
||||
from autometabuilder.utils import load_metadata
|
||||
metadata = load_metadata()
|
||||
plugins = metadata.get("workflow_plugins", {})
|
||||
return {"result": {"plugins": plugins}}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "web.register_routes",
|
||||
"version": "1.0.0",
|
||||
"description": "Register Flask routes from JSON configuration",
|
||||
"main": "web_register_routes.py",
|
||||
"author": "AutoMetabuilder",
|
||||
"category": "web"
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
"""Workflow plugin: register routes from JSON configuration."""
|
||||
from flask import Blueprint, jsonify, request
|
||||
|
||||
|
||||
def run(runtime, inputs):
|
||||
"""
|
||||
Register routes from JSON configuration.
|
||||
|
||||
This allows routes to be defined declaratively in the workflow JSON
|
||||
rather than in Python code.
|
||||
|
||||
Inputs:
|
||||
blueprint_name: Name for the blueprint (required)
|
||||
routes: List of route configurations (required)
|
||||
Each route should have:
|
||||
- path: The URL path (e.g., "/api/navigation")
|
||||
- methods: List of HTTP methods (default: ["GET"])
|
||||
- handler: Name of the handler function or plugin to call
|
||||
- handler_type: "plugin" or "function" (default: "plugin")
|
||||
- handler_inputs: Inputs to pass to the plugin/function (optional)
|
||||
|
||||
Returns:
|
||||
dict: Contains the blueprint in result
|
||||
"""
|
||||
app = runtime.context.get("flask_app")
|
||||
if not app:
|
||||
return {"error": "Flask app not found in context. Run web.create_flask_app first."}
|
||||
|
||||
blueprint_name = inputs.get("blueprint_name")
|
||||
if not blueprint_name:
|
||||
return {"error": "blueprint_name is required"}
|
||||
|
||||
routes = inputs.get("routes", [])
|
||||
if not routes:
|
||||
return {"error": "routes list is required"}
|
||||
|
||||
# Create blueprint
|
||||
blueprint = Blueprint(blueprint_name, __name__)
|
||||
|
||||
# Register each route
|
||||
for route_config in routes:
|
||||
path = route_config.get("path")
|
||||
if not path:
|
||||
runtime.logger.error(f"Route missing 'path' in {blueprint_name}")
|
||||
continue
|
||||
|
||||
methods = route_config.get("methods", ["GET"])
|
||||
handler = route_config.get("handler")
|
||||
handler_type = route_config.get("handler_type", "plugin")
|
||||
handler_inputs = route_config.get("handler_inputs", {})
|
||||
|
||||
if not handler:
|
||||
runtime.logger.error(f"Route {path} missing 'handler' in {blueprint_name}")
|
||||
continue
|
||||
|
||||
# Create route handler function
|
||||
def make_handler(handler_name, h_type, h_inputs):
|
||||
"""Create a handler function with captured variables."""
|
||||
def route_handler():
|
||||
try:
|
||||
if h_type == "plugin":
|
||||
# Execute plugin and return result
|
||||
from autometabuilder.workflow.plugin_registry import load_plugin_map, PluginRegistry
|
||||
plugin_map = load_plugin_map()
|
||||
registry = PluginRegistry(plugin_map)
|
||||
plugin = registry.get(handler_name)
|
||||
|
||||
if not plugin:
|
||||
return jsonify({"error": f"Plugin {handler_name} not found"}), 500
|
||||
|
||||
# Merge handler inputs with any request data
|
||||
inputs_copy = dict(h_inputs)
|
||||
if request.method == "POST" and request.is_json:
|
||||
inputs_copy.update(request.get_json())
|
||||
|
||||
result = plugin(runtime, inputs_copy)
|
||||
|
||||
# If result has a "result" key, return that
|
||||
if isinstance(result, dict) and "result" in result:
|
||||
return jsonify(result["result"]), 200
|
||||
|
||||
return jsonify(result), 200
|
||||
else:
|
||||
# For function type, could load and call a function
|
||||
return jsonify({"error": "Function handler type not yet implemented"}), 500
|
||||
|
||||
except Exception as e:
|
||||
runtime.logger.error(f"Error in route handler {path}: {e}")
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
return route_handler
|
||||
|
||||
# Add route to blueprint
|
||||
handler_func = make_handler(handler, handler_type, handler_inputs)
|
||||
handler_func.__name__ = f"{blueprint_name}_{path.replace('/', '_')}"
|
||||
blueprint.add_url_rule(path, view_func=handler_func, methods=methods)
|
||||
|
||||
# Register blueprint with app
|
||||
app.register_blueprint(blueprint)
|
||||
|
||||
return {
|
||||
"result": blueprint,
|
||||
"message": f"Registered blueprint '{blueprint_name}' with {len(routes)} routes"
|
||||
}
|
||||
Reference in New Issue
Block a user