services updated
This commit is contained in:
22
Events/Engine/__init__.py
Normal file
22
Events/Engine/__init__.py
Normal file
@@ -0,0 +1,22 @@
|
||||
"""ApiEvents package initialization.
|
||||
|
||||
This module serves as the main entry point for the ApiEvents package,
|
||||
making common utilities and base classes available for all API services.
|
||||
"""
|
||||
|
||||
from .abstract_class import (
|
||||
MethodToEvent,
|
||||
PageInfo,
|
||||
CategoryCluster,
|
||||
Event,
|
||||
)
|
||||
|
||||
# from .base_request_model import BaseRequestModel, DictRequestModel
|
||||
|
||||
# Re-export commonly used classes
|
||||
__all__ = [
|
||||
"MethodToEvent",
|
||||
"PageInfo",
|
||||
"CategoryCluster",
|
||||
"Event",
|
||||
]
|
||||
452
Events/Engine/abstract_class.py
Normal file
452
Events/Engine/abstract_class.py
Normal file
@@ -0,0 +1,452 @@
|
||||
from abc import abstractmethod
|
||||
from typing import Any, Dict, List, Optional, Callable
|
||||
from uuid import UUID
|
||||
|
||||
from ApiLayers.AllConfigs.Redis.configs import RedisCategoryKeys
|
||||
from Events.base_request_model import STATIC_PATH
|
||||
|
||||
|
||||
class PageComponent:
|
||||
|
||||
NAME: str
|
||||
URL: str
|
||||
FETCH_URL: str
|
||||
LANGUAGE_MODELS: Dict[str, Any]
|
||||
TYPE_COMPONENT: Optional[str] = "Page"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
url: str,
|
||||
# fetch_url: str,
|
||||
language_models: Dict[str, Any],
|
||||
):
|
||||
self.NAME = name
|
||||
self.URL = url
|
||||
# self.FETCH_URL = fetch_url
|
||||
self.LANGUAGE_MODELS = language_models
|
||||
|
||||
def set_language_models(self, language_models: Dict[str, Any]):
|
||||
self.LANGUAGE_MODELS = language_models
|
||||
|
||||
@property
|
||||
def language_models(self):
|
||||
return self.LANGUAGE_MODELS
|
||||
|
||||
def as_dict(self):
|
||||
return {
|
||||
"name": self.NAME,
|
||||
"url": self.URL,
|
||||
"language_models": self.LANGUAGE_MODELS,
|
||||
# "fetch_url": self.FETCH_URL,
|
||||
}
|
||||
|
||||
|
||||
class PageInfo:
|
||||
"""
|
||||
match_page: {
|
||||
"/dashboard?site=AccountCluster": [
|
||||
"/accounts/create",
|
||||
"/accounts/update",
|
||||
"/accounts/list",
|
||||
],
|
||||
"/update?site=AccountCluster": ["/accounts/update"],
|
||||
"/create?site=AccountCluster": ["/accounts/create"],
|
||||
},
|
||||
|
||||
RedisValidation = dict(
|
||||
NAME="AccountCluster",
|
||||
PREFIX="/accounts",
|
||||
URL="/dashboard?site=AccountCluster",
|
||||
ICON="Building",
|
||||
INFO={
|
||||
"en": {
|
||||
"page": "Account Records for reaching user all types account information",
|
||||
},
|
||||
"tr": {
|
||||
"page": "Kullanıcı tüm hesap bilgilerine ulaşmak için Hesap Kayıtları",
|
||||
},
|
||||
},
|
||||
SUB_COMPONENTS={
|
||||
"/accounts/create": {
|
||||
"SITE_URL": "/events/create?site=AccountCluster",
|
||||
"COMPONENT": "Link",
|
||||
"PREFIX_URL": "/accounts/create",
|
||||
"INFO": {
|
||||
"en": {
|
||||
"page": "Create Account Records",
|
||||
"actions": "Actions",
|
||||
"table": "Table",
|
||||
},
|
||||
"tr": {
|
||||
"page": "Hesap Kayıdı Oluştur",
|
||||
"actions": "Aksiyonlar",
|
||||
"table": "Tablo",
|
||||
},
|
||||
},
|
||||
"INSTRUCTIONS": None,
|
||||
},
|
||||
"/accounts/list": {
|
||||
"SITE_URL": "/events/dashboard?site=AccountCluster",
|
||||
"COMPONENT": "Table",
|
||||
"PREFIX_URL": "/accounts/list",
|
||||
"INFO": {
|
||||
"en": { "page": "List Account Records" },
|
||||
"tr": { "page": "Hesap Kayıtlarını Listele" },
|
||||
},
|
||||
"INSTRUCTIONS": {
|
||||
"headers": {
|
||||
"store": True,
|
||||
"url": "/validations/header",
|
||||
"data": {
|
||||
"event_code": "/accounts/list",
|
||||
"asked_field": "headers",
|
||||
},
|
||||
},
|
||||
"data": {
|
||||
"store": True,
|
||||
"url": "/accounts/list",
|
||||
"data": {
|
||||
"page": 1,
|
||||
"limit": 1,
|
||||
"order_by": "uu_id",
|
||||
"order_type": "desc",
|
||||
"query": None,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
"""
|
||||
|
||||
NAME: str
|
||||
PAGE_URL: str
|
||||
INFO: Dict[str, Any]
|
||||
URL: str = ""
|
||||
ENDPOINTS: Dict[str, Any]
|
||||
LANGUAGE_MODELS: Dict[str, Any]
|
||||
SUB_COMPONENTS: Optional[list["PageComponent"]] = None
|
||||
INSTRUCTIONS: Optional[Dict[str, Any]] = None
|
||||
TEMPLATE_UI: Optional[str] = "LCU"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
icon: str,
|
||||
url: str,
|
||||
info: Optional[Dict[str, Any]] = None,
|
||||
endpoints: Optional[Dict[str, Any]] = None,
|
||||
language_models: Optional[Dict[str, Any]] = None,
|
||||
sub_components: Optional[list[Dict[str, Any]]] = None,
|
||||
instructions: Optional[Dict[str, Any]] = None,
|
||||
template_ui: Optional[str] = "LCU",
|
||||
):
|
||||
self.NAME = name
|
||||
self.LANGUAGE_MODELS = language_models
|
||||
self.ICON = icon
|
||||
self.URL = url
|
||||
self.SUB_COMPONENTS = sub_components
|
||||
self.ENDPOINTS = endpoints
|
||||
self.INFO = info
|
||||
self.INSTRUCTIONS = instructions
|
||||
self.TEMPLATE_UI = template_ui
|
||||
|
||||
@property
|
||||
def endpoints(self):
|
||||
return self.ENDPOINTS
|
||||
|
||||
@property
|
||||
def sub_components(self):
|
||||
return self.SUB_COMPONENTS
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
as_dict = {
|
||||
"NAME": self.NAME,
|
||||
"ICON": self.ICON,
|
||||
"URL": self.URL,
|
||||
"TEMPLATE_UI": self.TEMPLATE_UI,
|
||||
"LANGUAGE_MODELS": self.LANGUAGE_MODELS,
|
||||
"INFO": self.INFO,
|
||||
"SUB_COMPONENTS": self.SUB_COMPONENTS,
|
||||
}
|
||||
return as_dict
|
||||
|
||||
|
||||
class Event:
|
||||
|
||||
KEY_: str # static string uuid.uuid4().__str__()
|
||||
RESPONSE_VALIDATOR: Optional[Any]
|
||||
REQUEST_VALIDATOR: Optional[Any]
|
||||
DESCRIPTION: str
|
||||
LANGUAGE_MODELS: list
|
||||
STATICS: str
|
||||
EXTRA_OPTIONS: Optional[Dict[str, Any]] = None
|
||||
endpoint_callable: Any
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
key: str | UUID,
|
||||
description: str,
|
||||
language_models: list[Dict[str, Dict]],
|
||||
statics: str = None,
|
||||
request_validator: Optional[Any] = None,
|
||||
response_validator: Optional[Any] = None,
|
||||
extra_options: Optional[Dict[str, Any]] = None,
|
||||
) -> None:
|
||||
self.NAME = name
|
||||
self.KEY_ = key
|
||||
self.REQUEST_VALIDATOR = request_validator
|
||||
self.RESPONSE_VALIDATOR = response_validator
|
||||
self.STATICS = statics
|
||||
self.LANGUAGE_MODELS = language_models
|
||||
self.DESCRIPTION = description
|
||||
self.EXTRA_OPTIONS = extra_options
|
||||
|
||||
@property
|
||||
def is_static_response(self):
|
||||
return bool(self.STATICS)
|
||||
|
||||
@property
|
||||
def static_response(self):
|
||||
from Services.Redis.Actions.actions import RedisActions
|
||||
from ApiLayers.AllConfigs.Redis.configs import RedisValidationKeysAction
|
||||
|
||||
if self.is_static_response:
|
||||
static_response = RedisActions.get_json(
|
||||
list_keys=[
|
||||
f"{RedisValidationKeysAction.static_response_key}:{self.STATICS}"
|
||||
]
|
||||
)
|
||||
if static_response.status:
|
||||
return static_response.first
|
||||
return None
|
||||
|
||||
@property
|
||||
def static_key(self):
|
||||
return self.STATICS
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
return f"This is an event of {self.name}. Description: {self.DESCRIPTION}"
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.NAME
|
||||
|
||||
@property
|
||||
def key(self) -> str:
|
||||
return str(self.KEY_)
|
||||
|
||||
@abstractmethod
|
||||
def endpoint_callable(self, **kwargs) -> Any:
|
||||
"""
|
||||
Retrieves the endpoint function based on the event key.
|
||||
"""
|
||||
return self.endpoint_callable(**kwargs)
|
||||
|
||||
|
||||
class MethodToEvent:
|
||||
"""
|
||||
for all endpoint callable
|
||||
def endpoint_callable(request: Request, data: PydanticModel):
|
||||
return cls.retrieve_event(event_function_code).retrieve_callable(token_dict, data)
|
||||
[Table.__language_model__ | Dict[__language_model__]]
|
||||
[Dict[ErrorCode][lang]]
|
||||
|
||||
"""
|
||||
|
||||
EVENTS: dict[str, Event]
|
||||
HEADER_LANGUAGE_MODELS: list[Dict]
|
||||
ERRORS_LANGUAGE_MODELS: Optional[list[Dict]]
|
||||
URL: str
|
||||
METHOD: str
|
||||
SUMMARY: str
|
||||
DESCRIPTION: str
|
||||
DECORATORS_LIST: Optional[Callable] = []
|
||||
EXTRA_OPTIONS: Optional[Dict[str, Any]] = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
events: dict[str, Event],
|
||||
headers: list[Dict],
|
||||
url: str,
|
||||
method: str,
|
||||
summary: str,
|
||||
description: str,
|
||||
decorators_list: Optional[List[Callable]] = None,
|
||||
errors: Optional[list[Dict]] = None,
|
||||
extra_options: Optional[Dict[str, Any]] = None,
|
||||
):
|
||||
self.EVENTS = events
|
||||
self.URL = url
|
||||
self.METHOD = method
|
||||
self.SUMMARY = summary
|
||||
self.NAME = name
|
||||
self.DESCRIPTION = description
|
||||
self.DECORATORS_LIST = decorators_list
|
||||
self.HEADER_LANGUAGE_MODELS = headers
|
||||
self.ERRORS_LANGUAGE_MODELS = errors
|
||||
self.EXTRA_OPTIONS = extra_options
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.NAME
|
||||
|
||||
def retrieve_all_event_keys(self):
|
||||
"""
|
||||
Retrieves all event keys from the events list.
|
||||
"""
|
||||
return [str(event_key) for event_key in self.EVENTS.keys()]
|
||||
|
||||
def retrieve_event(self, event_function_code: str) -> Event:
|
||||
"""
|
||||
Retrieves the event object from the events list based on the event function code.
|
||||
"""
|
||||
if found_event := self.EVENTS.get(event_function_code, None):
|
||||
return found_event
|
||||
raise ValueError(f"Event with function code {event_function_code} not found")
|
||||
|
||||
def retrieve_redis_value(self, cluster: "CategoryCluster") -> Dict:
|
||||
"""
|
||||
Key("METHOD_FUNCTION_CODES:{ClusterToMethod}:MethodEvent:Endpoint") : Value([FUNCTION_CODE, ...])
|
||||
"""
|
||||
prefix_url = f"{cluster.PREFIX}{self.URL}"
|
||||
redis_key = f"{RedisCategoryKeys.METHOD_FUNCTION_CODES}:{cluster.name}:{self.name}:{prefix_url}"
|
||||
return {redis_key: self.retrieve_all_event_keys()}
|
||||
|
||||
@staticmethod
|
||||
def endpoint_callable(**kwargs):
|
||||
"""
|
||||
return cls.retrieve_event(event_function_code).retrieve_callable(token_dict, data)
|
||||
"""
|
||||
raise NotImplementedError("Endpoint callable method is not implemented")
|
||||
|
||||
|
||||
class CategoryCluster:
|
||||
|
||||
TAGS: list
|
||||
PREFIX: str
|
||||
PAGEINFO: Optional[Dict["str", PageInfo]]
|
||||
DESCRIPTION: str
|
||||
ENDPOINTS: dict[str, MethodToEvent] # {"MethodToEvent": MethodToEvent, ...}
|
||||
SUBCATEGORY: Optional[List["CategoryCluster"]] # [CategoryCluster, ...]
|
||||
TEMPLATE_UI: Optional[str] = "LCU" # LCU as List/Create/Update
|
||||
MAPPING: Optional[List[Dict[str, Any]]] # [{"key": "value"}, ...]
|
||||
INCLUDE_IN_SCHEMA: Optional[bool] = True
|
||||
IS_CLIENT: Optional[bool] = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
tags: list,
|
||||
prefix: str,
|
||||
description: str,
|
||||
endpoints: dict[str, MethodToEvent],
|
||||
sub_category: list,
|
||||
mapping: Optional[List[Dict[str, Any]]] = None,
|
||||
pageinfo: Optional[Dict["str", PageInfo]] = None,
|
||||
template_ui: Optional[str] = "LCU",
|
||||
include_in_schema: Optional[bool] = True,
|
||||
is_client: Optional[bool] = False,
|
||||
):
|
||||
self.NAME = name
|
||||
self.TAGS = tags
|
||||
self.PREFIX = prefix
|
||||
self.PAGEINFO = pageinfo
|
||||
self.DESCRIPTION = description
|
||||
self.ENDPOINTS = endpoints or {}
|
||||
self.SUBCATEGORY = sub_category or []
|
||||
self.INCLUDE_IN_SCHEMA = include_in_schema
|
||||
self.MAPPING = mapping
|
||||
self.TEMPLATE_UI = template_ui
|
||||
self.IS_CLIENT = is_client
|
||||
|
||||
@property
|
||||
def is_clickable(self):
|
||||
return bool(self.SUBCATEGORY)
|
||||
|
||||
@property
|
||||
def is_client(self):
|
||||
return self.IS_CLIENT
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.NAME
|
||||
|
||||
def get_redis_cluster_index_value(self):
|
||||
"""
|
||||
RedisCategoryKeys.CLUSTER_2_METHOD_EVENT
|
||||
Returns the class name and function codes for the class.
|
||||
"""
|
||||
dict_cluster_2_method, list_endpoints = {}, [
|
||||
i.name for i in self.ENDPOINTS.values()
|
||||
]
|
||||
for endpoint_name in list_endpoints:
|
||||
dict_cluster_2_method[endpoint_name] = self.name
|
||||
dict_cluster_2_method[self.name] = list_endpoints
|
||||
return dict_cluster_2_method
|
||||
|
||||
def retrieve_all_function_codes(self):
|
||||
"""
|
||||
Retrieves all function codes by iterating over the events list.
|
||||
"""
|
||||
all_function_codes = []
|
||||
for event_method in self.ENDPOINTS.values():
|
||||
all_function_codes.extend(
|
||||
[str(event_key) for event_key in event_method.EVENTS.keys()]
|
||||
)
|
||||
return all_function_codes
|
||||
|
||||
def retrieve_redis_value(self) -> Dict:
|
||||
"""
|
||||
Create Redis Key and Value from function codes
|
||||
Key(CLUSTER_FUNCTION_CODES:ClusterToMethod) : Value(PAGE_INFO, [FUNCTION_CODE, ...])
|
||||
"""
|
||||
return {
|
||||
f"{RedisCategoryKeys.CLUSTER_FUNCTION_CODES}:{self.name}": self.retrieve_all_function_codes()
|
||||
}
|
||||
|
||||
def retrieve_page_info(self):
|
||||
"""
|
||||
PAGE_INFO:ClusterToMethod = {"PageInfo": {...}, "subCategory": PAGE_INFO:ClusterToMethod}
|
||||
return {"prefix": self.PREFIX, "mapping": self.MAPPING, **page_infos}
|
||||
"""
|
||||
page_infos = {}
|
||||
print("def retrieve_page_info self.PAGEINFO", self.PAGEINFO)
|
||||
if isinstance(self.PAGEINFO, dict):
|
||||
for page_key, page_info in dict(self.PAGEINFO).items():
|
||||
if page_info_dict := getattr(page_info, "as_dict", None):
|
||||
page_infos[page_key] = page_info_dict
|
||||
return {"prefix": self.PREFIX, "mapping": self.MAPPING, **page_infos}
|
||||
if hasattr(self.PAGEINFO, "as_dict"):
|
||||
return {
|
||||
"prefix": self.PREFIX,
|
||||
"mapping": self.MAPPING,
|
||||
**self.PAGEINFO.as_dict,
|
||||
}
|
||||
return {"prefix": self.PREFIX, "mapping": self.MAPPING}
|
||||
|
||||
|
||||
class LanguageModels:
|
||||
SITE_URL: str
|
||||
COMPONENT: str = "Table"
|
||||
PREFIX_URL: str = ""
|
||||
PAGE_INFO: dict
|
||||
STATIC_PATH: str = STATIC_PATH
|
||||
ICON: str = ""
|
||||
|
||||
def as_dict(self):
|
||||
return {
|
||||
"SITE_URL": f"/{self.STATIC_PATH}{self.SITE_URL}",
|
||||
"COMPONENT": self.COMPONENT,
|
||||
"PREFIX_URL": self.PREFIX_URL,
|
||||
"PAGE_INFO": self.PAGE_INFO,
|
||||
"ICON": self.ICON,
|
||||
}
|
||||
|
||||
|
||||
DefaultClusterName = "site"
|
||||
46
Events/Engine/set_defaults/category_cluster_models.py
Normal file
46
Events/Engine/set_defaults/category_cluster_models.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from Events.Engine import CategoryCluster
|
||||
|
||||
|
||||
class CategoryBulk:
|
||||
|
||||
def __init__(self, category_cluster: CategoryCluster = None, name: str = ""):
|
||||
self.category_cluster = category_cluster
|
||||
self.name = name
|
||||
|
||||
|
||||
class CategoryClusterController:
|
||||
|
||||
imports_dict: list[CategoryBulk] = []
|
||||
|
||||
@property
|
||||
def imports(self):
|
||||
return self.imports_dict
|
||||
|
||||
@classmethod
|
||||
def import_all_category_clusters(cls, category_clusters):
|
||||
"""
|
||||
Imports all category clusters from the given list
|
||||
{ "category_cluster_name": "category_cluster_module" }
|
||||
"""
|
||||
if not hasattr(category_clusters, "__all__"):
|
||||
raise ValueError(
|
||||
f"Given module {str(category_clusters)} does not have __all__ attribute"
|
||||
)
|
||||
for iter_module in [str(item) for item in category_clusters.__all__]:
|
||||
# CategoryCluster which represent api routers for each category
|
||||
cls.imports_dict.append(
|
||||
CategoryBulk(
|
||||
category_cluster=getattr(category_clusters, iter_module, None),
|
||||
name=iter_module,
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def as_dict(cls):
|
||||
to_dict = {}
|
||||
for cluster in cls.imports_dict:
|
||||
to_dict[cluster.name] = cluster.category_cluster
|
||||
return to_dict
|
||||
|
||||
|
||||
cluster_controller = CategoryClusterController()
|
||||
108
Events/Engine/set_defaults/prepare_redis_items.py
Normal file
108
Events/Engine/set_defaults/prepare_redis_items.py
Normal file
@@ -0,0 +1,108 @@
|
||||
from ApiLayers.AllConfigs.Redis.configs import (
|
||||
RedisCategoryKeys,
|
||||
RedisCategoryPageInfoKeysAction,
|
||||
)
|
||||
|
||||
|
||||
class PrepareRedisItems:
|
||||
|
||||
MENU_FIRST_LAYER_KEY: str = RedisCategoryKeys.MENU_FIRST_LAYER
|
||||
MENU_FIRST_LAYER_VALUE: set[str] = set()
|
||||
CLUSTER_INDEX_KEY: str = RedisCategoryKeys.CLUSTER_INDEX
|
||||
CLUSTER_INDEX_VALUE: dict = {}
|
||||
CLUSTER_FUNCTION_CODES_KEY: str = RedisCategoryKeys.CLUSTER_FUNCTION_CODES
|
||||
CLUSTER_FUNCTION_CODES_VALUE: dict = {}
|
||||
METHOD_FUNCTION_CODES_KEY: str = RedisCategoryKeys.METHOD_FUNCTION_CODES
|
||||
METHOD_FUNCTION_CODES_VALUE: dict = {}
|
||||
ENDPOINT2CLASS_KEY: str = RedisCategoryKeys.ENDPOINT2CLASS
|
||||
ENDPOINT2CLASS_VALUE: dict = {}
|
||||
PAGE_INFO_KEY: str = RedisCategoryPageInfoKeysAction.page_index
|
||||
PAGE_INFO_VALUE: dict = {}
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
return {
|
||||
self.MENU_FIRST_LAYER_KEY: list(self.MENU_FIRST_LAYER_VALUE),
|
||||
self.CLUSTER_INDEX_KEY: self.CLUSTER_INDEX_VALUE,
|
||||
self.CLUSTER_FUNCTION_CODES_KEY: self.CLUSTER_FUNCTION_CODES_VALUE,
|
||||
self.METHOD_FUNCTION_CODES_KEY: self.METHOD_FUNCTION_CODES_VALUE,
|
||||
self.ENDPOINT2CLASS_KEY: self.ENDPOINT2CLASS_VALUE,
|
||||
self.PAGE_INFO_KEY: self.PAGE_INFO_VALUE,
|
||||
}
|
||||
|
||||
|
||||
class DecoratorModule:
|
||||
|
||||
@staticmethod
|
||||
def get_all_decorators(func):
|
||||
"""
|
||||
Get all decorators of a function, excluding the original function itself.
|
||||
Returns a list of decorator functions in the order they were applied.
|
||||
"""
|
||||
decorators = []
|
||||
current_func = func
|
||||
original_qualname = getattr(func, "__qualname__", "")
|
||||
|
||||
while hasattr(current_func, "__wrapped__"):
|
||||
if hasattr(current_func, "__closure__") and current_func.__closure__:
|
||||
for cell in current_func.__closure__:
|
||||
decorator = cell.cell_contents
|
||||
# Only add if it's a callable and not the original function
|
||||
if (
|
||||
callable(decorator)
|
||||
and getattr(decorator, "__qualname__", "") != original_qualname
|
||||
):
|
||||
decorators.append(decorator)
|
||||
current_func = current_func.__wrapped__
|
||||
return list(
|
||||
dict.fromkeys(decorators)
|
||||
) # Remove duplicates while preserving order
|
||||
|
||||
@staticmethod
|
||||
def get_actual_decorators(method_endpoint):
|
||||
original_qualname = getattr(
|
||||
method_endpoint.endpoint_callable, "__qualname__", ""
|
||||
)
|
||||
actual_decorators = [
|
||||
d
|
||||
for d in method_endpoint.DECORATORS_LIST or []
|
||||
if callable(d) and getattr(d, "__qualname__", "") != original_qualname
|
||||
]
|
||||
return actual_decorators
|
||||
|
||||
@classmethod
|
||||
def apply_decorators(cls, method_endpoint):
|
||||
# Get the original function and its qualname
|
||||
function_callable = method_endpoint.endpoint_callable
|
||||
# Filter out the original function and apply decorators
|
||||
actual_decorators = cls.get_actual_decorators(method_endpoint)
|
||||
|
||||
# Apply decorators in reverse order (to match @ syntax behavior)
|
||||
for decorator in reversed(actual_decorators):
|
||||
try:
|
||||
function_callable = decorator(function_callable)
|
||||
except Exception as e:
|
||||
print(
|
||||
f"Warning: Failed to apply decorator {decorator.__qualname__}: {str(e)}"
|
||||
)
|
||||
|
||||
method_endpoint.endpoint_callable = function_callable
|
||||
|
||||
# Get the final list of applied decorators (for debugging)
|
||||
applied_decorators = cls.get_all_decorators(method_endpoint.endpoint_callable)
|
||||
applied_decorators_qualname = [
|
||||
getattr(d, "__qualname__", str(d)) for d in applied_decorators
|
||||
]
|
||||
if applied_decorators:
|
||||
print(
|
||||
f"Applied decorators for {method_endpoint.name}:",
|
||||
applied_decorators_qualname,
|
||||
)
|
||||
return applied_decorators_qualname
|
||||
|
||||
@classmethod
|
||||
def list_qualname(cls, method_endpoint_list):
|
||||
return [
|
||||
getattr(method_endpoint, "__qualname__", "")
|
||||
for method_endpoint in method_endpoint_list
|
||||
]
|
||||
17
Events/Engine/set_defaults/run.py
Normal file
17
Events/Engine/set_defaults/run.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from Events.AllEvents.events_file import events_list
|
||||
|
||||
from .category_cluster_models import cluster_controller
|
||||
|
||||
|
||||
def get_cluster_controller_group():
|
||||
for cluster in events_list:
|
||||
cluster_controller.import_all_category_clusters(cluster)
|
||||
return cluster_controller
|
||||
|
||||
|
||||
"""
|
||||
prepare_routing = PrepareRouting(cluster_controller_group=cluster_controller)
|
||||
prepare_events = PrepareEvents(cluster_controller_group=cluster_controller)
|
||||
print(set_items_2_redis)
|
||||
print(prepare_routing)
|
||||
"""
|
||||
226
Events/Engine/set_defaults/setClusters.py
Normal file
226
Events/Engine/set_defaults/setClusters.py
Normal file
@@ -0,0 +1,226 @@
|
||||
from typing import Any
|
||||
|
||||
from ApiLayers.ApiServices.Cluster.create_router import (
|
||||
CreateRouterFromCluster,
|
||||
CreateEndpointFromCluster,
|
||||
)
|
||||
from ApiLayers.AllConfigs.Redis.configs import (
|
||||
RedisCategoryKeys,
|
||||
RedisCategoryPageInfoKeys,
|
||||
)
|
||||
from Events.Engine.abstract_class import CategoryCluster
|
||||
from Services.Redis.Actions.actions import RedisActions
|
||||
from Services.Redis.Models.cluster import RedisList
|
||||
|
||||
from .prepare_redis_items import DecoratorModule, PrepareRedisItems
|
||||
from .category_cluster_models import CategoryClusterController
|
||||
|
||||
|
||||
class PrepareRouting(DecoratorModule):
|
||||
|
||||
__routers_list: list[Any] = list()
|
||||
__endpoints_list: list[Any] = list()
|
||||
__safe_endpoint_list: list[Any] = list()
|
||||
|
||||
def __init__(self, cluster_controller_group: CategoryClusterController):
|
||||
self.cluster_controller_group = cluster_controller_group
|
||||
self.prepare_needs()
|
||||
|
||||
def __str__(self):
|
||||
return f"\nPrepared Routing:\n\n{self.routers}\n\n{self.endpoints}\n\n{self.safe_endpoints}\n"
|
||||
|
||||
@property
|
||||
def routers(self):
|
||||
return self.__routers_list
|
||||
|
||||
@property
|
||||
def endpoints(self):
|
||||
return self.__endpoints_list
|
||||
|
||||
@property
|
||||
def safe_endpoints(self):
|
||||
return self.__safe_endpoint_list
|
||||
|
||||
def create_endpoints(self, cluster: CategoryCluster, created_router):
|
||||
for method_endpoint in list(cluster.ENDPOINTS.values()):
|
||||
# Filter out the original function and apply decorators
|
||||
applied_decorators_qualname = self.apply_decorators(method_endpoint)
|
||||
# Register the endpoint with FastAPI router
|
||||
create_endpoint = CreateEndpointFromCluster(
|
||||
router=created_router, method_endpoint=method_endpoint
|
||||
)
|
||||
created_router = create_endpoint.router
|
||||
if "MiddlewareModule" in applied_decorators_qualname:
|
||||
self.__safe_endpoint_list.append(method_endpoint)
|
||||
self.__endpoints_list.append(method_endpoint)
|
||||
|
||||
def create_router(self, cluster: CategoryCluster):
|
||||
### Create Router Parameters create router for each cluster
|
||||
created_router = CreateRouterFromCluster(
|
||||
prefix=cluster.PREFIX,
|
||||
tags=cluster.TAGS,
|
||||
include_in_schema=cluster.INCLUDE_IN_SCHEMA,
|
||||
)
|
||||
self.__routers_list.append(created_router.router)
|
||||
return created_router.router
|
||||
|
||||
def prepare_needs(self):
|
||||
# @Pages iterate(ClusterToMethod)
|
||||
for cluster_control in self.cluster_controller_group.imports:
|
||||
cluster = cluster_control.category_cluster
|
||||
created_router = self.create_router(cluster)
|
||||
self.create_endpoints(cluster, created_router)
|
||||
|
||||
|
||||
class PrepareEvents(DecoratorModule):
|
||||
|
||||
def __init__(self, cluster_controller_group: CategoryClusterController):
|
||||
self.cluster_controller_group = cluster_controller_group
|
||||
self.valid_redis_items: PrepareRedisItems = PrepareRedisItems()
|
||||
self.prepare_needs()
|
||||
self.prepare_page_info()
|
||||
|
||||
def prepare_page_info(self):
|
||||
"""
|
||||
[SAVE]REDIS => PAGE_MENU_INDEX:PAGE_URL= {...PageInfo}
|
||||
"""
|
||||
for cluster_control in self.cluster_controller_group.imports:
|
||||
cluster = cluster_control.category_cluster
|
||||
if retrieve_page_info := cluster.retrieve_page_info():
|
||||
self.valid_redis_items.PAGE_INFO_VALUE.update(
|
||||
{
|
||||
f"{self.valid_redis_items.PAGE_INFO_KEY}:{cluster.name}": retrieve_page_info
|
||||
}
|
||||
)
|
||||
|
||||
def prepare_needs(self):
|
||||
# @Pages iterate(ClusterToMethod)
|
||||
for cluster_control in self.cluster_controller_group.imports:
|
||||
cluster = cluster_control.category_cluster
|
||||
### Create Redis Parameters
|
||||
# [SAVE]REDIS => MENU_FIRST_LAYER = [ClusterToMethod, ...]
|
||||
if cluster.is_client:
|
||||
self.valid_redis_items.MENU_FIRST_LAYER_VALUE.add(cluster.name)
|
||||
# [SAVE]REDIS => CLUSTER_INDEX = {ClusterToMethod: [MethodEvent, ...], "MethodEvent": "ClusterToMethod"}
|
||||
self.valid_redis_items.CLUSTER_INDEX_VALUE.update(
|
||||
cluster.get_redis_cluster_index_value()
|
||||
)
|
||||
# [SAVE]REDIS => CLUSTER_FUNCTION_CODES = {"ClusterToMethod"} : [FUNCTION_CODE, ...]}
|
||||
self.valid_redis_items.CLUSTER_FUNCTION_CODES_VALUE.update(
|
||||
{
|
||||
f"{self.valid_redis_items.CLUSTER_FUNCTION_CODES_KEY}:{cluster.name}": tuple(
|
||||
cluster.retrieve_all_function_codes()
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
for method_endpoint in list(cluster.ENDPOINTS.values()):
|
||||
# [SAVE]REDIS => ENDPOINT2CLASS = {MethodEvent: Endpoint("/.../.../..."), ...}
|
||||
self.valid_redis_items.ENDPOINT2CLASS_VALUE.update(
|
||||
{
|
||||
f"{cluster.name}:{method_endpoint.name}": f"{cluster.PREFIX}{method_endpoint.URL}"
|
||||
}
|
||||
)
|
||||
self.valid_redis_items.ENDPOINT2CLASS_VALUE.update(
|
||||
{
|
||||
f"{cluster.PREFIX}{method_endpoint.URL}": f"{cluster.name}:{method_endpoint.name}"
|
||||
}
|
||||
)
|
||||
# [SAVE]REDIS => METHOD_FUNCTION_CODES:MethodEvent:Endpoint = [FUNCTION_CODE, ...]
|
||||
self.valid_redis_items.METHOD_FUNCTION_CODES_VALUE.update(
|
||||
method_endpoint.retrieve_redis_value(cluster=cluster)
|
||||
)
|
||||
|
||||
|
||||
class SetItems2Redis:
|
||||
|
||||
std_out: str = ""
|
||||
|
||||
def __init__(self, prepare_events: PrepareEvents):
|
||||
self.prepare_events = prepare_events
|
||||
self.set_items()
|
||||
|
||||
def __str__(self):
|
||||
return f"\nSetItems2Redis:\n\n{self.std_out}"
|
||||
|
||||
def set_items(self):
|
||||
|
||||
dict_prep = self.prepare_events.valid_redis_items.as_dict
|
||||
for (
|
||||
redis_values_to_delete,
|
||||
redis_key_type,
|
||||
) in RedisCategoryKeys.__annotations__.items():
|
||||
if isinstance(redis_key_type, str):
|
||||
continue
|
||||
RedisActions.delete(list_keys=[f"{redis_values_to_delete}*"])
|
||||
|
||||
for (
|
||||
redis_values_to_delete,
|
||||
redis_key_type,
|
||||
) in RedisCategoryPageInfoKeys.__annotations__.items():
|
||||
if isinstance(redis_key_type, str):
|
||||
continue
|
||||
RedisActions.delete(list_keys=[f"{redis_values_to_delete}*"])
|
||||
|
||||
# Save MENU_FIRST_LAYER to Redis
|
||||
redis_list = RedisList(redis_key=RedisCategoryKeys.MENU_FIRST_LAYER)
|
||||
RedisActions.set_json(
|
||||
list_keys=redis_list.to_list(),
|
||||
value=dict_prep.get(RedisCategoryKeys.MENU_FIRST_LAYER),
|
||||
)
|
||||
self.std_out += f"{RedisCategoryKeys.MENU_FIRST_LAYER}: {dict_prep.get(RedisCategoryKeys.MENU_FIRST_LAYER)}\n"
|
||||
|
||||
# Save CLUSTER_INDEX to Redis
|
||||
redis_list = RedisList(redis_key=RedisCategoryKeys.CLUSTER_INDEX)
|
||||
RedisActions.set_json(
|
||||
list_keys=redis_list.to_list(),
|
||||
value=dict_prep.get(RedisCategoryKeys.CLUSTER_INDEX),
|
||||
)
|
||||
self.std_out += f"\n{RedisCategoryKeys.CLUSTER_INDEX}: {dict_prep.get(RedisCategoryKeys.CLUSTER_INDEX)}\n"
|
||||
|
||||
# Save CLUSTER_FUNCTION_CODES to Redis by iterating over the dict
|
||||
for redis_key, redis_value in dict_prep.get(
|
||||
RedisCategoryKeys.CLUSTER_FUNCTION_CODES
|
||||
).items():
|
||||
redis_list = RedisList(redis_key=redis_key)
|
||||
RedisActions.set_json(
|
||||
list_keys=redis_list.to_list(), value=list(redis_value)
|
||||
)
|
||||
self.std_out += f"\n{RedisCategoryKeys.CLUSTER_FUNCTION_CODES}: {dict_prep.get(RedisCategoryKeys.CLUSTER_FUNCTION_CODES)}\n"
|
||||
|
||||
# Save METHOD_FUNCTION_CODES to Redis by iterating over the dict
|
||||
for redis_key, redis_value in dict_prep.get(
|
||||
RedisCategoryKeys.METHOD_FUNCTION_CODES
|
||||
).items():
|
||||
redis_list = RedisList(redis_key=redis_key)
|
||||
RedisActions.set_json(
|
||||
list_keys=redis_list.to_list(), value=list(redis_value)
|
||||
)
|
||||
self.std_out += f"\n{RedisCategoryKeys.METHOD_FUNCTION_CODES}: {dict_prep.get(RedisCategoryKeys.METHOD_FUNCTION_CODES)}\n"
|
||||
|
||||
# Save ENDPOINT2CLASS to Redis by iterating over the dict
|
||||
for redis_key, redis_value in dict_prep.get(
|
||||
RedisCategoryKeys.ENDPOINT2CLASS
|
||||
).items():
|
||||
redis_list = RedisList(
|
||||
redis_key=f"{RedisCategoryKeys.ENDPOINT2CLASS}:{redis_key}\n"
|
||||
)
|
||||
RedisActions.set_json(list_keys=redis_list.to_list(), value=redis_value)
|
||||
self.std_out += f"\n{RedisCategoryKeys.ENDPOINT2CLASS}: {dict_prep.get(RedisCategoryKeys.ENDPOINT2CLASS)}\n"
|
||||
|
||||
RedisActions.set_json(
|
||||
list_keys=[f"{RedisCategoryKeys.REBUILD}"],
|
||||
value={
|
||||
f"{RedisCategoryKeys.MENU_FIRST_LAYER}": True,
|
||||
f"{RedisCategoryKeys.CLUSTER_INDEX}": True,
|
||||
f"{RedisCategoryKeys.CLUSTER_FUNCTION_CODES}": True,
|
||||
f"{RedisCategoryKeys.METHOD_FUNCTION_CODES}": True,
|
||||
f"{RedisCategoryKeys.ENDPOINT2CLASS}": True,
|
||||
},
|
||||
)
|
||||
|
||||
for redis_key, redis_value in dict_prep.get(
|
||||
PrepareRedisItems.PAGE_INFO_KEY
|
||||
).items():
|
||||
redis_list = RedisList(redis_key=redis_key)
|
||||
RedisActions.set_json(list_keys=redis_list.to_list(), value=redis_value)
|
||||
Reference in New Issue
Block a user