ums.management.main
1# Agenten Plattform 2# 3# (c) 2024 Magnus Bender 4# Institute of Humanities-Centered Artificial Intelligence (CHAI) 5# Universitaet Hamburg 6# https://www.chai.uni-hamburg.de/~bender 7# 8# source code released under the terms of GNU Public License Version 3 9# https://www.gnu.org/licenses/gpl-3.0.txt 10 11import os 12 13from typing import List 14from datetime import datetime 15 16from fastapi import FastAPI, Request, BackgroundTasks, HTTPException 17from fastapi.responses import HTMLResponse 18from fastapi.templating import Jinja2Templates 19 20from jinja2.runtime import Undefined as JinjaUndefined 21 22from ums.management.interface import Interface 23from ums.management.db import DB, MessageDbRow 24from ums.management.process import MessageProcessor 25 26from ums.utils import AgentMessage, AgentResponse, TEMPLATE_PATH 27 28class WebMain(): 29 30 _TIME_FORMAT = "%H:%M:%S %d.%m.%Y" 31 32 def __init__(self): 33 self._init_app() 34 self._init_templates() 35 36 self.db = DB() 37 self.msg_process = MessageProcessor(self.db) 38 39 self._add_routes() 40 self._add_routers() 41 42 43 def _init_app(self): 44 self.app = FastAPI( 45 title="Agenten Plattform", 46 description="Agenten Plattform – Management", 47 openapi_url="/api/schema.json", 48 docs_url='/api', 49 redoc_url=None 50 ) 51 52 def _init_templates(self): 53 self.template = Jinja2Templates( 54 directory=TEMPLATE_PATH, 55 auto_reload=True 56 ) 57 58 def timestamp2date(t:int|JinjaUndefined) -> str: 59 return "" if isinstance(t, JinjaUndefined) \ 60 else datetime.fromtimestamp(t).strftime(self._TIME_FORMAT) 61 self.template.env.globals["timestamp2date"] = timestamp2date 62 63 def date2timestamp(d:str|JinjaUndefined) -> int|str: 64 return "" if isinstance(d, JinjaUndefined) \ 65 else int(datetime.strptime(d, self._TIME_FORMAT).timestamp()) 66 self.template.env.globals["date2timestamp"] = date2timestamp 67 68 69 def _add_routers(self): 70 interface_router = Interface(self.template, self.db) 71 self.app.include_router(interface_router.router) 72 73 def _add_routes(self): 74 75 @self.app.get("/index", response_class=HTMLResponse, summary="Link list") 76 def index(request: Request): 77 return self.template.TemplateResponse( 78 'index.html', 79 {"request" : request} 80 ) 81 82 @self.app.post("/message", summary="Send a message to the management", tags=['agents']) 83 def message(request: Request, message:AgentMessage, background_tasks: BackgroundTasks) -> AgentResponse: 84 85 receiver = request.headers['host'] 86 if ':' in receiver: 87 receiver = receiver[:receiver.rindex(':')] 88 89 sender = request.headers['x-forwarded-for'] 90 91 return self.msg_process.new_message(sender, receiver, message, background_tasks) 92 93 @self.app.get("/list", summary="Get list of messages (like table)", tags=["cli, agents"]) 94 def list(id:str|None=None, sender:str|None=None, recipient:str|None=None, 95 processed:bool|None=None, solution:bool|None=None, 96 time_after:int|None=None, time_before:int|None=None, 97 limit:int=10, offset:int=0 98 ) -> List[MessageDbRow]: 99 100 db_args = { 101 "limit" : limit, 102 "offset" : offset 103 } 104 105 for v,n in ( 106 (id,'id'), (sender,'sender'), (recipient,'recipient'), 107 (processed,'processed'), (solution,'solution'), 108 (time_after, 'time_after'), (time_before, 'time_before') 109 ): 110 if not v is None: 111 db_args[n] = v 112 113 return [row for row in self.db.iterate(**db_args)] 114 115 @self.app.get("/list/single", summary="Get a single message", tags=["cli, agents"]) 116 def status(count:int) -> MessageDbRow: 117 msg = self.db.by_count(count) 118 if msg is None: 119 raise HTTPException(status_code=404, detail="Message not found") 120 121 return msg 122 123if __name__ == "ums.management.main" and os.environ.get('SERVE', 'false').lower() == 'true': 124 main = WebMain() 125 app = main.app
class
WebMain:
29class WebMain(): 30 31 _TIME_FORMAT = "%H:%M:%S %d.%m.%Y" 32 33 def __init__(self): 34 self._init_app() 35 self._init_templates() 36 37 self.db = DB() 38 self.msg_process = MessageProcessor(self.db) 39 40 self._add_routes() 41 self._add_routers() 42 43 44 def _init_app(self): 45 self.app = FastAPI( 46 title="Agenten Plattform", 47 description="Agenten Plattform – Management", 48 openapi_url="/api/schema.json", 49 docs_url='/api', 50 redoc_url=None 51 ) 52 53 def _init_templates(self): 54 self.template = Jinja2Templates( 55 directory=TEMPLATE_PATH, 56 auto_reload=True 57 ) 58 59 def timestamp2date(t:int|JinjaUndefined) -> str: 60 return "" if isinstance(t, JinjaUndefined) \ 61 else datetime.fromtimestamp(t).strftime(self._TIME_FORMAT) 62 self.template.env.globals["timestamp2date"] = timestamp2date 63 64 def date2timestamp(d:str|JinjaUndefined) -> int|str: 65 return "" if isinstance(d, JinjaUndefined) \ 66 else int(datetime.strptime(d, self._TIME_FORMAT).timestamp()) 67 self.template.env.globals["date2timestamp"] = date2timestamp 68 69 70 def _add_routers(self): 71 interface_router = Interface(self.template, self.db) 72 self.app.include_router(interface_router.router) 73 74 def _add_routes(self): 75 76 @self.app.get("/index", response_class=HTMLResponse, summary="Link list") 77 def index(request: Request): 78 return self.template.TemplateResponse( 79 'index.html', 80 {"request" : request} 81 ) 82 83 @self.app.post("/message", summary="Send a message to the management", tags=['agents']) 84 def message(request: Request, message:AgentMessage, background_tasks: BackgroundTasks) -> AgentResponse: 85 86 receiver = request.headers['host'] 87 if ':' in receiver: 88 receiver = receiver[:receiver.rindex(':')] 89 90 sender = request.headers['x-forwarded-for'] 91 92 return self.msg_process.new_message(sender, receiver, message, background_tasks) 93 94 @self.app.get("/list", summary="Get list of messages (like table)", tags=["cli, agents"]) 95 def list(id:str|None=None, sender:str|None=None, recipient:str|None=None, 96 processed:bool|None=None, solution:bool|None=None, 97 time_after:int|None=None, time_before:int|None=None, 98 limit:int=10, offset:int=0 99 ) -> List[MessageDbRow]: 100 101 db_args = { 102 "limit" : limit, 103 "offset" : offset 104 } 105 106 for v,n in ( 107 (id,'id'), (sender,'sender'), (recipient,'recipient'), 108 (processed,'processed'), (solution,'solution'), 109 (time_after, 'time_after'), (time_before, 'time_before') 110 ): 111 if not v is None: 112 db_args[n] = v 113 114 return [row for row in self.db.iterate(**db_args)] 115 116 @self.app.get("/list/single", summary="Get a single message", tags=["cli, agents"]) 117 def status(count:int) -> MessageDbRow: 118 msg = self.db.by_count(count) 119 if msg is None: 120 raise HTTPException(status_code=404, detail="Message not found") 121 122 return msg