new api service and logic implemented
This commit is contained in:
175
Scratches/endpoint.py
Normal file
175
Scratches/endpoint.py
Normal file
@@ -0,0 +1,175 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional, Dict, Any, Callable
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import Union
|
||||
|
||||
|
||||
# First, let's create our category models
|
||||
class CategoryBase(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
|
||||
|
||||
class CategoryCreate(CategoryBase):
|
||||
parent_id: Optional[str] = None
|
||||
|
||||
|
||||
class CategoryResponse(CategoryBase):
|
||||
children: List['CategoryResponse'] = []
|
||||
parent_id: Optional[str] = None
|
||||
|
||||
|
||||
# Category data structure for handling the hierarchy
|
||||
@dataclass
|
||||
class CategoryNode:
|
||||
id: str
|
||||
name: str
|
||||
description: Optional[str]
|
||||
parent_id: Optional[str] = None
|
||||
children: List['CategoryNode'] = field(default_factory=list)
|
||||
|
||||
|
||||
# Category Service for managing the hierarchy
|
||||
class CategoryService:
|
||||
def __init__(self):
|
||||
self.categories: Dict[str, CategoryNode] = {}
|
||||
|
||||
def add_category(self, category: CategoryCreate) -> CategoryNode:
|
||||
node = CategoryNode(
|
||||
id=category.id,
|
||||
name=category.name,
|
||||
description=category.description,
|
||||
parent_id=category.parent_id
|
||||
)
|
||||
|
||||
self.categories[category.id] = node
|
||||
|
||||
if category.parent_id and category.parent_id in self.categories:
|
||||
parent = self.categories[category.parent_id]
|
||||
parent.children.append(node)
|
||||
|
||||
return node
|
||||
|
||||
def get_category_tree(self, category_id: str) -> Optional[CategoryNode]:
|
||||
return self.categories.get(category_id)
|
||||
|
||||
def get_category_path(self, category_id: str) -> List[CategoryNode]:
|
||||
path = []
|
||||
current = self.categories.get(category_id)
|
||||
|
||||
while current:
|
||||
path.append(current)
|
||||
current = self.categories.get(current.parent_id) if current.parent_id else None
|
||||
|
||||
return list(reversed(path))
|
||||
|
||||
|
||||
# Factory for creating category endpoints
|
||||
class CategoryEndpointFactory:
|
||||
def __init__(self, category_service: CategoryService):
|
||||
self.category_service = category_service
|
||||
|
||||
def create_route_config(self, base_prefix: str) -> RouteFactoryConfig:
|
||||
endpoints = [
|
||||
# Create category endpoint
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=base_prefix,
|
||||
url_endpoint="/categories",
|
||||
url_of_endpoint=f"{base_prefix}/categories",
|
||||
endpoint="/categories",
|
||||
method="POST",
|
||||
summary="Create new category",
|
||||
description="Create a new category with optional parent",
|
||||
endpoint_function=self.create_category,
|
||||
request_model=CategoryCreate,
|
||||
response_model=CategoryResponse,
|
||||
is_auth_required=True
|
||||
),
|
||||
|
||||
# Get category tree endpoint
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=base_prefix,
|
||||
url_endpoint="/categories/{category_id}",
|
||||
url_of_endpoint=f"{base_prefix}/categories/{{category_id}}",
|
||||
endpoint="/categories/{category_id}",
|
||||
method="GET",
|
||||
summary="Get category tree",
|
||||
description="Get category and its children",
|
||||
endpoint_function=self.get_category_tree,
|
||||
response_model=CategoryResponse,
|
||||
is_auth_required=True
|
||||
),
|
||||
|
||||
# Get category path endpoint
|
||||
EndpointFactoryConfig(
|
||||
url_prefix=base_prefix,
|
||||
url_endpoint="/categories/{category_id}/path",
|
||||
url_of_endpoint=f"{base_prefix}/categories/{{category_id}}/path",
|
||||
endpoint="/categories/{category_id}/path",
|
||||
method="GET",
|
||||
summary="Get category path",
|
||||
description="Get full path from root to this category",
|
||||
endpoint_function=self.get_category_path,
|
||||
response_model=List[CategoryResponse],
|
||||
is_auth_required=True
|
||||
)
|
||||
]
|
||||
|
||||
return RouteFactoryConfig(
|
||||
name="categories",
|
||||
tags=["Categories"],
|
||||
prefix=base_prefix,
|
||||
endpoints=endpoints
|
||||
)
|
||||
|
||||
async def create_category(self, category: CategoryCreate) -> CategoryResponse:
|
||||
node = self.category_service.add_category(category)
|
||||
return self._convert_to_response(node)
|
||||
|
||||
async def get_category_tree(self, category_id: str) -> CategoryResponse:
|
||||
node = self.category_service.get_category_tree(category_id)
|
||||
if not node:
|
||||
raise HTTPException(status_code=404, detail="Category not found")
|
||||
return self._convert_to_response(node)
|
||||
|
||||
async def get_category_path(self, category_id: str) -> List[CategoryResponse]:
|
||||
path = self.category_service.get_category_path(category_id)
|
||||
if not path:
|
||||
raise HTTPException(status_code=404, detail="Category not found")
|
||||
return [self._convert_to_response(node) for node in path]
|
||||
|
||||
def _convert_to_response(self, node: CategoryNode) -> CategoryResponse:
|
||||
return CategoryResponse(
|
||||
id=node.id,
|
||||
name=node.name,
|
||||
description=node.description,
|
||||
parent_id=node.parent_id,
|
||||
children=[self._convert_to_response(child) for child in node.children]
|
||||
)
|
||||
|
||||
|
||||
# Usage example
|
||||
def create_category_router(base_prefix: str = "/api/v1") -> APIRouter:
|
||||
category_service = CategoryService()
|
||||
factory = CategoryEndpointFactory(category_service)
|
||||
route_config = factory.create_route_config(base_prefix)
|
||||
|
||||
router = APIRouter(
|
||||
prefix=route_config.prefix,
|
||||
tags=route_config.tags
|
||||
)
|
||||
|
||||
for endpoint in route_config.endpoints:
|
||||
router.add_api_route(
|
||||
path=endpoint.endpoint,
|
||||
endpoint=endpoint.endpoint_function,
|
||||
methods=[endpoint.method],
|
||||
response_model=endpoint.response_model,
|
||||
summary=endpoint.summary,
|
||||
description=endpoint.description,
|
||||
**endpoint.extra_options
|
||||
)
|
||||
|
||||
return router
|
||||
Reference in New Issue
Block a user