redis implemntations and api setup completed
This commit is contained in:
42
Events/Engine/set_defaults/category_cluster_models.py
Normal file
42
Events/Engine/set_defaults/category_cluster_models.py
Normal file
@@ -0,0 +1,42 @@
|
||||
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()
|
||||
84
Events/Engine/set_defaults/prepare_redis_items.py
Normal file
84
Events/Engine/set_defaults/prepare_redis_items.py
Normal file
@@ -0,0 +1,84 @@
|
||||
from ApiLayers.AllConfigs.Redis.configs import RedisCategoryKeys
|
||||
|
||||
|
||||
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 = {}
|
||||
|
||||
@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,
|
||||
}
|
||||
|
||||
|
||||
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]
|
||||
@@ -1,2 +1,16 @@
|
||||
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)
|
||||
set_items_2_redis = SetItems2Redis(prepare_events=prepare_events)
|
||||
print(set_items_2_redis)
|
||||
print(prepare_routing)
|
||||
"""
|
||||
|
||||
@@ -1,7 +1,171 @@
|
||||
import AllEvents.auth as auths_events
|
||||
import AllEvents.events as events_events
|
||||
import AllEvents.validations as validations_events
|
||||
from typing import Any
|
||||
|
||||
from ApiLayers.ApiServices.Cluster.create_router import (
|
||||
CreateRouterFromCluster,
|
||||
CreateEndpointFromCluster
|
||||
)
|
||||
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
|
||||
|
||||
|
||||
for event in [*auths_events.__all__, *events_events.__all__, *validations_events.__all__]:
|
||||
print(event)
|
||||
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):
|
||||
# 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()
|
||||
|
||||
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, ...]
|
||||
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 = {
|
||||
f"{self.valid_redis_items.CLUSTER_FUNCTION_CODES_KEY}:{cluster.name}" : tuple(cluster.retrieve_all_function_codes())
|
||||
}
|
||||
|
||||
for method_endpoint in list(cluster.ENDPOINTS):
|
||||
# [SAVE]REDIS => ENDPOINT2CLASS = {MethodEvent: Endpoint("/.../.../..."), ...}
|
||||
self.valid_redis_items.ENDPOINT2CLASS_VALUE.update(
|
||||
{f"{cluster.name}:{method_endpoint.name}": method_endpoint.URL}
|
||||
)
|
||||
self.valid_redis_items.ENDPOINT2CLASS_VALUE.update(
|
||||
{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_name=cluster.name)
|
||||
)
|
||||
|
||||
|
||||
class SetItems2Redis:
|
||||
|
||||
std_out: str = ""
|
||||
|
||||
def __init__(self, prepare_events: PrepareEvents):
|
||||
self.prepare_events = prepare_events
|
||||
self.set_items()
|
||||
|
||||
def __str__(self):
|
||||
self.std_out = f"\nSetItems2Redis:\n\n{self.std_out}"
|
||||
return self.std_out
|
||||
|
||||
def set_items(self):
|
||||
from ApiLayers.AllConfigs.Redis.configs import RedisCategoryKeys
|
||||
dict_prep = self.prepare_events.valid_redis_items.as_dict
|
||||
RedisActions.delete(
|
||||
list_keys=[
|
||||
f"{RedisCategoryKeys.MENU_FIRST_LAYER}:*",
|
||||
f"{RedisCategoryKeys.CLUSTER_INDEX}:*",
|
||||
f"{RedisCategoryKeys.CLUSTER_FUNCTION_CODES}:*",
|
||||
f"{RedisCategoryKeys.METHOD_FUNCTION_CODES}:*"
|
||||
f"{RedisCategoryKeys.ENDPOINT2CLASS}:*",
|
||||
]
|
||||
)
|
||||
|
||||
# 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=False
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user