Improved command management to reduce the number of instances

This commit is contained in:
2025-12-21 11:14:02 +01:00
parent 9f69a6bc5b
commit 2f808ed226
8 changed files with 100 additions and 19 deletions

View File

@@ -1,5 +1,6 @@
import inspect
import json
import logging
import uuid
from typing import Optional
@@ -8,6 +9,8 @@ from myutils.observable import NotObservableError, ObservableResultCollector
from myfasthtml.core.constants import Routes, ROUTE_ROOT
from myfasthtml.core.utils import flatten
logger = logging.getLogger("Commands")
class Command:
"""
@@ -26,6 +29,33 @@ class Command:
:type description: str
"""
@staticmethod
def process_key(key, name, owner, args, kwargs):
def _compute_from_args():
res = []
for arg in args:
if hasattr(arg, "get_full_id"):
res.append(arg.get_full_id())
else:
res.append(str(arg))
return "-".join(res)
# special management when kwargs are provided
# In this situation,
# either there is no parameter (so one single instance of the command is enough)
# or the parameter is a kwargs (so the parameters are provided when the command is called)
if (key is None
and owner is not None
and args is None # args is not provided
):
key = f"{owner.get_full_id()}-{name}"
key = key.replace("#{args}", _compute_from_args())
key = key.replace("#{id}", owner.get_full_id())
key = key.replace("#{id-name-args}", f"{owner.get_full_id()}-{name}-{_compute_from_args()}")
return key
def __init__(self, name,
description,
owner=None,
@@ -47,10 +77,20 @@ class Command:
self._callback_parameters = dict(inspect.signature(callback).parameters) if callback else {}
self._key = key
# special management when kwargs are provided
# In this situation,
# either there is no parameter (so one single instance of the command is enough)
# or the parameter is a kwargs (so the parameters are provided when the command is called)
if (self._key is None
and self.owner is not None
and args is None # args is not provided
):
self._key = f"{owner.get_full_id()}-{name}"
# register the command
if auto_register:
if key in CommandsManager.commands_by_key:
self.id = CommandsManager.commands_by_key[key].id
if self._key in CommandsManager.commands_by_key:
self.id = CommandsManager.commands_by_key[self._key].id
else:
CommandsManager.register(self)
@@ -78,6 +118,7 @@ class Command:
return res
def execute(self, client_response: dict = None):
logger.debug(f"Executing command {self.name}")
with ObservableResultCollector(self._bindings) as collector:
kwargs = self._create_kwargs(self.default_kwargs,
client_response,
@@ -87,6 +128,7 @@ class Command:
ret_from_bound_commands = []
if self.owner:
for command in self.owner.get_bound_commands(self.name):
logger.debug(f" will execute bound command {command.name}...")
r = command.execute(client_response)
ret_from_bound_commands.append(r) # it will be flatten if needed later

View File

@@ -12,7 +12,7 @@ from myfasthtml.core.constants import Routes, ROUTE_ROOT
from myfasthtml.test.MyFT import MyFT
utils_app, utils_rt = fast_app()
logger = logging.getLogger("Commands")
logger = logging.getLogger("Routing")
def mount_if_not_exists(app, path: str, sub_app):