From 9f2effb6b4abcc8e3de783b78b9e7a9ebe2403ce Mon Sep 17 00:00:00 2001 From: mbruzon Date: Fri, 29 May 2026 14:55:02 +0200 Subject: [PATCH] #wip: WebSockets Servers y HTTP Servers done. --- Python/Abstracts/HTTPServersAbstract.py | 2 +- Python/Abstracts/WebSocketServersAbstract.py | 4 +- Python/Application/AnP.py | 13 +++- Python/Drivers/HTTPDriver.py | 16 ---- Python/Drivers/WebSocketServerDriver.py | 22 +++--- .../Abstracts/HTTPServersAbstractInterface.py | 19 +++++ .../WebSocketServersAbstractInterface.py | 19 +++++ Python/Interfaces/Application/AnPInterface.py | 2 + .../Managers/HTTPServersManagerInterface.py | 26 +++++++ .../WebSocketServersManagerInterface.py | 4 +- Python/Managers/HTTPServersManager.py | 75 +++++++++++++++++++ Python/Managers/WebSocketServersManager.py | 5 +- 12 files changed, 171 insertions(+), 36 deletions(-) create mode 100644 Python/Interfaces/Abstracts/HTTPServersAbstractInterface.py create mode 100644 Python/Interfaces/Abstracts/WebSocketServersAbstractInterface.py create mode 100644 Python/Interfaces/Managers/HTTPServersManagerInterface.py diff --git a/Python/Abstracts/HTTPServersAbstract.py b/Python/Abstracts/HTTPServersAbstract.py index 2cd4187..29c0f06 100644 --- a/Python/Abstracts/HTTPServersAbstract.py +++ b/Python/Abstracts/HTTPServersAbstract.py @@ -11,7 +11,7 @@ class HTTPServersAbstract(ABC): DEFAULT_PORT:int = 8000 DEFAULT_HOST:str = "" - def __init__(self:Self, anp:Any, inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None) -> None: + def __init__(self:Self, anp:AnPInterface, inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None) -> None: self.anp:AnPInterface = anp self.__inputs:dict[str, Any|None] = Common.get_dictionary(inputs) self.host:str = self.DEFAULT_PORT diff --git a/Python/Abstracts/WebSocketServersAbstract.py b/Python/Abstracts/WebSocketServersAbstract.py index 0dddd01..071de89 100644 --- a/Python/Abstracts/WebSocketServersAbstract.py +++ b/Python/Abstracts/WebSocketServersAbstract.py @@ -3,11 +3,13 @@ from typing import Any, Self, Optional, Sequence from abc import ABC, abstractmethod +from Interfaces.Application.AnPInterface import AnPInterface from Application.Event import Event class WebSocketServersAbstract(ABC): - def __init__(self:Self, inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None) -> None: + def __init__(self:Self, anp:AnPInterface, inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None) -> None: + self.anp:AnPInterface = anp self.on_new_client:Event = Event() self.on_message:Event = Event() self.on_close:Event = Event() diff --git a/Python/Application/AnP.py b/Python/Application/AnP.py index 916a8d3..bbe027b 100644 --- a/Python/Application/AnP.py +++ b/Python/Application/AnP.py @@ -15,6 +15,7 @@ from Managers.DispatchesManager import DispatchesManager from Managers.IndexesManager import IndexesManager from Managers.RoutesManager import RoutesManager from Managers.WebSocketServersManager import WebSocketServersManager +from Managers.HTTPServersManager import HTTPServersManager from Drivers.HTTPDriver import HTTPDriver from Utils.Common import Common from Utils.Patterns import RE @@ -47,7 +48,8 @@ class AnP: self.indexes:IndexesManager = IndexesManager(self) self.routes:RoutesManager = RoutesManager(self) self.web_socket_servers:WebSocketServersManager = WebSocketServersManager(self) - self.http_server:HTTPDriver = HTTPDriver(self) + self.http_servers:HTTPServersManager = HTTPServersManager(self) + # self.http_server:HTTPDriver = HTTPDriver(self) def update(self:Self) -> None: self.settings.update() @@ -61,7 +63,8 @@ class AnP: self.indexes.update() self.routes.update() self.web_socket_servers.update() - self.http_server.update() + self.http_servers.update() + # self.http_server.update() def reset(self:Self) -> None: self.settings.reset() @@ -75,12 +78,14 @@ class AnP: self.indexes.reset() self.routes.reset() self.web_socket_servers.reset() - self.http_server.reset() + self.http_servers.reset() + # self.http_server.reset() def close(self:Self) -> None: self.__working = False self.web_socket_servers.close() - self.http_server.close() + self.http_servers.close() + # self.http_server.close() def working(self:Self) -> bool: return self.__working diff --git a/Python/Drivers/HTTPDriver.py b/Python/Drivers/HTTPDriver.py index 8cac4ce..d70d610 100644 --- a/Python/Drivers/HTTPDriver.py +++ b/Python/Drivers/HTTPDriver.py @@ -109,22 +109,6 @@ class HTTPDriver(HTTPServersAbstract): self.__server.shutdown() self.__server = None - def update(self:Self) -> None: - - self.close() - - self.__port = self.anp.settings.get(("http_server_port", "http_port", "port"), self.__inputs, self.__port) - self.__host = self.anp.settings.get(("http_server_host", "http_host", "host"), self.__inputs, self.__host) - - self.start() - - def reset(self:Self) -> None: - - self.__port = 8000 - self.__host = "" - - self.update() - def __run_service(self:Self) -> None: self.__server = HTTPServer((self.__host, self.__port), self.HTTPRequestHandler) self.__server.anp = self.anp diff --git a/Python/Drivers/WebSocketServerDriver.py b/Python/Drivers/WebSocketServerDriver.py index a232b5f..c39a246 100644 --- a/Python/Drivers/WebSocketServerDriver.py +++ b/Python/Drivers/WebSocketServerDriver.py @@ -14,7 +14,7 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract): def __init__(self:Self, anp:AnPInterface, inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None) -> None: super().__init__(anp, inputs) - + self.__server:WebSocketServer self.__clients:dict[int, WebSocketClient] = {} self.__host:str = anp.settings.get(("web_socket_server_host", "host"), inputs, "") @@ -48,8 +48,8 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract): except Exception as exception: self.anp.exception(exception, "web_socket_server_client_close_exception", { "client": id, - "port": self.__port, - "host": self.__host + "port": self.port, + "host": self.host }) del self.__clients[id] @@ -64,8 +64,8 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract): self.anp.print("info", "web_socket_server_client_connected", { "client": id, - "port": self.__port, - "host": self.__host, + "port": self.port, + "host": self.host, "client_host" : client.remote_address[0], "client_port" : client.remote_address[1] }) @@ -79,8 +79,8 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract): except Exception as exception: self.anp.exception(exception, "web_socket_server_client_exception", { "client": id, - "port": self.__port, - "host": self.__host + "port": self.port, + "host": self.host }) self.on_error.execute(id, exception) finally: @@ -88,8 +88,8 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract): self.on_close.execute(id) self.anp.print("info", "web_socket_server_client_disconnected", { "client": id, - "port": self.__port, - "host": self.__host + "port": self.port, + "host": self.host }) def send(self:Self, data:str, ids:int|Sequence[int]) -> bool: @@ -104,8 +104,8 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract): except Exception as exception: self.anp.exception(exception, "web_socket_server_client_send_exception", { "client": id, - "port": self.__port, - "host": self.__host + "port": self.port, + "host": self.host }) success = False diff --git a/Python/Interfaces/Abstracts/HTTPServersAbstractInterface.py b/Python/Interfaces/Abstracts/HTTPServersAbstractInterface.py new file mode 100644 index 0000000..0748213 --- /dev/null +++ b/Python/Interfaces/Abstracts/HTTPServersAbstractInterface.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from abc import ABC, abstractmethod +from typing import Self + +class HTTPServersAbstractInterface(ABC): + + @abstractmethod + def start(self:Self) -> None:pass + + @abstractmethod + def close(self:Self) -> None:pass + + @abstractmethod + def update(self:Self) -> None:pass + + @abstractmethod + def reset(self:Self) -> None:pass \ No newline at end of file diff --git a/Python/Interfaces/Abstracts/WebSocketServersAbstractInterface.py b/Python/Interfaces/Abstracts/WebSocketServersAbstractInterface.py new file mode 100644 index 0000000..a6af92f --- /dev/null +++ b/Python/Interfaces/Abstracts/WebSocketServersAbstractInterface.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from typing import Any, Self, Optional, Sequence +from abc import ABC, abstractmethod + +class WebSocketServersAbstractInterface(ABC): + + @abstractmethod + def start(self:Self) -> None:pass + + @abstractmethod + def close(self:Self) -> None:pass + + @abstractmethod + def close_client(self:Self, id:int) -> None:pass + + @abstractmethod + def send(self:Self, data:Any|None, ids:Optional[int|Sequence[int]] = None) -> None:pass \ No newline at end of file diff --git a/Python/Interfaces/Application/AnPInterface.py b/Python/Interfaces/Application/AnPInterface.py index 98b5119..5e3ba54 100644 --- a/Python/Interfaces/Application/AnPInterface.py +++ b/Python/Interfaces/Application/AnPInterface.py @@ -13,6 +13,7 @@ from Interfaces.Managers.DispatchesManagerInterface import DispatchesManagerInte from Interfaces.Managers.IndexesManagerInterface import IndexesManagerInterface from Interfaces.Managers.RoutesManagerInterface import RoutesManagerInterface from Interfaces.Managers.WebSocketServersManagerInterface import WebSocketServersManagerInterface +from Interfaces.Managers.HTTPServersManagerInterface import HTTPServersManagerInterface class AnPInterface(ABC): @@ -27,6 +28,7 @@ class AnPInterface(ABC): self.indexes:IndexesManagerInterface = None self.routes:RoutesManagerInterface = None self.web_socket_servers:WebSocketServersManagerInterface = None + self.http_servers:HTTPServersManagerInterface = None @abstractmethod def update(self:Self) -> None:pass diff --git a/Python/Interfaces/Managers/HTTPServersManagerInterface.py b/Python/Interfaces/Managers/HTTPServersManagerInterface.py new file mode 100644 index 0000000..37ecaff --- /dev/null +++ b/Python/Interfaces/Managers/HTTPServersManagerInterface.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from typing import Self, Sequence, Any +from abc import ABC, abstractmethod +from Interfaces.Abstracts.HTTPServersAbstractInterface import HTTPServersAbstractInterface + +class HTTPServersManagerInterface(ABC): + + @abstractmethod + def update(self:Self) -> None:pass + + @abstractmethod + def reset(self:Self) -> None:pass + + @abstractmethod + def close(self:Self) -> None:pass + + @abstractmethod + def add(self:Self, inputs:Any|None, overwrite:bool = False) -> None:pass + + @abstractmethod + def remove(self:Self, names:str|Sequence[str]) -> None:pass + + @abstractmethod + def get(self:Self, name:str) -> HTTPServersAbstractInterface|None:pass \ No newline at end of file diff --git a/Python/Interfaces/Managers/WebSocketServersManagerInterface.py b/Python/Interfaces/Managers/WebSocketServersManagerInterface.py index a3bad72..9ebe864 100644 --- a/Python/Interfaces/Managers/WebSocketServersManagerInterface.py +++ b/Python/Interfaces/Managers/WebSocketServersManagerInterface.py @@ -3,7 +3,7 @@ from typing import Any, Self, Optional, Sequence from abc import ABC, abstractmethod -from Abstracts.WebSocketServersAbstract import WebSocketServersAbstract +from Interfaces.Abstracts.WebSocketServersAbstractInterface import WebSocketServersAbstractInterface from Application.Event import Event class WebSocketServersManagerInterface(ABC): @@ -30,7 +30,7 @@ class WebSocketServersManagerInterface(ABC): def remove(self:Self, names:str|Sequence[str]) -> None:pass @abstractmethod - def get(self:Self, name:str) -> WebSocketServersAbstract|None:pass + def get(self:Self, name:str) -> WebSocketServersAbstractInterface|None:pass @abstractmethod def send(self:Self, diff --git a/Python/Managers/HTTPServersManager.py b/Python/Managers/HTTPServersManager.py index e69de29..14c7564 100644 --- a/Python/Managers/HTTPServersManager.py +++ b/Python/Managers/HTTPServersManager.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from typing import Self, Sequence, Any +from Interfaces.Application.AnPInterface import AnPInterface +from Abstracts.HTTPServersAbstract import HTTPServersAbstract +from Utils.Common import Common +from Utils.Checks import Check + +class HTTPServersManager: + + def __init__(self:Self, anp:AnPInterface) -> None: + self.anp:AnPInterface = anp + self.__servers:dict[str, HTTPServersAbstract] = {} + + self.update() + + def update(self:Self) -> None: + + key:str + + for key in ("default_http_server_files", "http_server_files", "default_http_server", "http_server"): + self.add(self.anp.settings.get(key), True) + + def reset(self:Self) -> None: + + self.__servers = {} + + self.update() + + def close(self:Self) -> None: + + server:HTTPServersAbstract + + for server in self.__servers.values(): + server.close() + self.__servers = {} + + def add(self:Self, inputs:Any|None, overwrite:bool = False) -> None: + + subinputs:dict[str, Any|None] + + for subinputs in Common.load_json(inputs, True): + + key:str + value:Any|None + + for key, value in subinputs.items(): + if isinstance(value, HTTPServersAbstract): + if overwrite or key not in self.__servers: + self.__servers[key] = value + elif Check.is_dictionary(value): + if overwrite or key not in self.__servers: + + _type:str|None = Common.get_value("type", value) + + if _type is None: + continue + + Class:type[HTTPServersAbstract] = self.anp.models.get(HTTPServersAbstract, _type) + + if Class and issubclass(Class, HTTPServersAbstract): + self.__servers[key] = Class(self.anp, value) + + def remove(self:Self, names:str|Sequence[str]) -> None: + for name in Common.get_key(names): + if name in self.__servers: + try: + self.__servers[name].close() + del self.__servers[name] + except Exception as exception: + self.anp.exception(exception, "http_server_close_exception", {"name": name}) + + def get(self:Self, name:str) -> HTTPServersAbstract|None: + return self.__servers.get(name) \ No newline at end of file diff --git a/Python/Managers/WebSocketServersManager.py b/Python/Managers/WebSocketServersManager.py index 0fde26b..23d287b 100644 --- a/Python/Managers/WebSocketServersManager.py +++ b/Python/Managers/WebSocketServersManager.py @@ -38,6 +38,9 @@ class WebSocketServersManager: self.update() def close(self:Self) -> None: + + web_socket:WebSocketServersAbstract + for web_socket in self.__web_sockets.values(): web_socket.close() self.__web_sockets = {} @@ -77,7 +80,7 @@ class WebSocketServersManager: Class and issubclass(Class, WebSocketServersAbstract) and self.__set(key, Class(self.anp, value)) def remove(self:Self, names:str|Sequence[str]) -> None: - for name in names if Check.is_array(names) else [names]: + for name in Common.get_keys(names): if name in self.__web_sockets: try: self.__web_sockets[name].close()