updated event and router stacks
This commit is contained in:
@@ -3,24 +3,27 @@ FROM python:3.12-slim
|
||||
WORKDIR /
|
||||
|
||||
# Install system dependencies and Poetry
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends gcc \
|
||||
&& rm -rf /var/lib/apt/lists/* && pip install --no-cache-dir poetry
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends gcc && rm -rf /var/lib/apt/lists/* && pip install --no-cache-dir poetry
|
||||
|
||||
# Copy Poetry configuration
|
||||
COPY /pyproject.toml ./pyproject.toml
|
||||
|
||||
# Configure Poetry and install dependencies with optimizations
|
||||
RUN poetry config virtualenvs.create false \
|
||||
&& poetry install --no-interaction --no-ansi --no-root --only main \
|
||||
&& pip cache purge && rm -rf ~/.cache/pypoetry
|
||||
RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi --no-root --only main \
|
||||
&& pip cache purge && rm -rf ~/.cache/pypoetry
|
||||
|
||||
# Copy application code
|
||||
COPY /ApiServices/IdentityService /ApiServices/IdentityService
|
||||
COPY /ApiControllers /ApiControllers
|
||||
COPY /ApiDefaults /ApiDefaults
|
||||
COPY /Controllers /Controllers
|
||||
COPY /Schemas /Schemas
|
||||
|
||||
COPY /ApiServices/IdentityService/Endpoints /ApiDefaults/Endpoints
|
||||
COPY /ApiServices/IdentityService/Events /ApiDefaults/Events
|
||||
COPY /ApiServices/IdentityService/Validations /ApiDefaults/Validations
|
||||
|
||||
# Set Python path to include app directory
|
||||
ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
# Run the application using the configured uvicorn server
|
||||
CMD ["poetry", "run", "python", "ApiServices/IdentityService/app.py"]
|
||||
CMD ["poetry", "run", "python", "ApiDefaults/app.py"]
|
||||
|
||||
@@ -2,9 +2,9 @@ import uuid
|
||||
|
||||
from fastapi import APIRouter, Request, Response, Header
|
||||
|
||||
from ApiServices.IdentityService.config import api_config
|
||||
from ApiServices.IdentityService.events.people.event import PeopleCluster
|
||||
from ApiServices.IdentityService.providers.token_provider import TokenProvider
|
||||
from ApiDefaults.config import api_config
|
||||
from Events.people.cluster import PeopleRouterCluster
|
||||
from ApiControllers.providers.token_provider import TokenProvider
|
||||
from Controllers.Postgres.pagination import PaginateOnly
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ people_route = APIRouter(prefix="/people", tags=["People"])
|
||||
|
||||
@people_route.post(
|
||||
path="/list",
|
||||
description="Test Template Route",
|
||||
description="List people endpoint",
|
||||
operation_id="f102db46-031a-43e4-966a-dae6896f985b",
|
||||
)
|
||||
def people_route_list(
|
||||
@@ -25,7 +25,7 @@ def people_route_list(
|
||||
tz: str = Header(None, alias="timezone"),
|
||||
):
|
||||
"""
|
||||
Test Template Route
|
||||
List people endpoint
|
||||
"""
|
||||
endpoint_code = "f102db46-031a-43e4-966a-dae6896f985b"
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
@@ -40,10 +40,10 @@ def people_route_list(
|
||||
event_key = TokenProvider.retrieve_event_codes(
|
||||
endpoint_code=endpoint_code, token=token_object
|
||||
)
|
||||
event_cluster_matched = PeopleCluster.PeopleListCluster.match_event(
|
||||
event_cluster_matched = PeopleRouterCluster.get_event_cluster("PeopleList").match_event(
|
||||
event_key=event_key
|
||||
)
|
||||
response.headers["X-Header"] = "Test Header GET"
|
||||
response.headers["X-Header"] = "List Header GET"
|
||||
if runner_callable := event_cluster_matched.event_callable(list_options=data):
|
||||
return runner_callable
|
||||
raise ValueError("Event key not found or multiple matches found")
|
||||
@@ -51,10 +51,10 @@ def people_route_list(
|
||||
|
||||
@people_route.post(
|
||||
path="/create",
|
||||
description="Test Template Route with Post Method",
|
||||
description="Create people endpoint",
|
||||
operation_id="eb465fde-337f-4b81-94cf-28c6d4f2b1b6",
|
||||
)
|
||||
def test_template_post(
|
||||
def people_route_create(
|
||||
request: Request,
|
||||
response: Response,
|
||||
language: str = Header(None, alias="language"),
|
||||
@@ -62,7 +62,7 @@ def test_template_post(
|
||||
tz: str = Header(None, alias="timezone"),
|
||||
):
|
||||
"""
|
||||
Test Template Route with Post Method
|
||||
Create people endpoint
|
||||
"""
|
||||
endpoint_code = "eb465fde-337f-4b81-94cf-28c6d4f2b1b6"
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
@@ -77,10 +77,10 @@ def test_template_post(
|
||||
event_key = TokenProvider.retrieve_event_codes(
|
||||
endpoint_code=endpoint_code, token=token_object
|
||||
)
|
||||
event_cluster_matched = PeopleCluster.PeopleCreateCluster.match_event(
|
||||
event_cluster_matched = PeopleRouterCluster.get_event_cluster("PeopleCreate").match_event(
|
||||
event_key=event_key
|
||||
)
|
||||
response.headers["X-Header"] = "Test Header POST"
|
||||
response.headers["X-Header"] = "Create Header POST"
|
||||
if runner_callable := event_cluster_matched.event_callable():
|
||||
return runner_callable
|
||||
raise ValueError("Event key not found or multiple matches found")
|
||||
@@ -88,10 +88,10 @@ def test_template_post(
|
||||
|
||||
@people_route.post(
|
||||
path="/update",
|
||||
description="Test Template Route with Post Method",
|
||||
description="Update people endpoint",
|
||||
operation_id="c9e5ba69-6915-43f5-8f9c-a5c2aa865b89",
|
||||
)
|
||||
def test_template_post(
|
||||
def people_route_update(
|
||||
request: Request,
|
||||
response: Response,
|
||||
language: str = Header(None, alias="language"),
|
||||
@@ -99,7 +99,7 @@ def test_template_post(
|
||||
tz: str = Header(None, alias="timezone"),
|
||||
):
|
||||
"""
|
||||
Test Template Route with Post Method
|
||||
Update people endpoint
|
||||
"""
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
endpoint_code = "c9e5ba69-6915-43f5-8f9c-a5c2aa865b89"
|
||||
@@ -114,10 +114,10 @@ def test_template_post(
|
||||
event_key = TokenProvider.retrieve_event_codes(
|
||||
endpoint_code=endpoint_code, token=token_object
|
||||
)
|
||||
event_cluster_matched = PeopleCluster.PeopleUpdateCluster.match_event(
|
||||
event_cluster_matched = PeopleRouterCluster.get_event_cluster("PeopleUpdate").match_event(
|
||||
event_key=event_key
|
||||
)
|
||||
response.headers["X-Header"] = "Test Header POST"
|
||||
response.headers["X-Header"] = "Update Header POST"
|
||||
if runner_callable := event_cluster_matched.event_callable():
|
||||
return runner_callable
|
||||
raise ValueError("Event key not found or multiple matches found")
|
||||
@@ -1,12 +1,11 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
# from .user.route import user_route
|
||||
from .people.route import people_route
|
||||
|
||||
|
||||
def get_routes() -> list[APIRouter]:
|
||||
from .people.route import people_route
|
||||
from .user.route import user_route
|
||||
return [
|
||||
# user_route,
|
||||
user_route,
|
||||
people_route
|
||||
]
|
||||
|
||||
107
ApiServices/IdentityService/Endpoints/user/route.py
Normal file
107
ApiServices/IdentityService/Endpoints/user/route.py
Normal file
@@ -0,0 +1,107 @@
|
||||
import uuid
|
||||
|
||||
from fastapi import APIRouter, Request, Response, Header
|
||||
|
||||
from ApiDefaults.config import api_config
|
||||
from Events.user.cluster import UserRouterCluster
|
||||
from ApiControllers.providers.token_provider import TokenProvider
|
||||
|
||||
|
||||
user_route = APIRouter(prefix="/user", tags=["User"])
|
||||
|
||||
|
||||
@user_route.post(
|
||||
path="/list",
|
||||
description="List users endpoint",
|
||||
operation_id="5bc09312-d3f2-4f47-baba-17c928706da8",
|
||||
)
|
||||
def user_list_route(
|
||||
request: Request,
|
||||
response: Response,
|
||||
language: str = Header(None, alias="language"),
|
||||
domain: str = Header(None, alias="domain"),
|
||||
tz: str = Header(None, alias="timezone"),
|
||||
):
|
||||
"""
|
||||
List users endpoint
|
||||
"""
|
||||
endpoint_code = "5bc09312-d3f2-4f47-baba-17c928706da8"
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
token_object = TokenProvider.get_dict_from_redis(token=token)
|
||||
event_key = TokenProvider.retrieve_event_codes(endpoint_code=endpoint_code, token=token_object)
|
||||
headers = {
|
||||
"language": language or "",
|
||||
"domain": domain or "",
|
||||
"eys-ext": f"{str(uuid.uuid4())}",
|
||||
"tz": tz or "GMT+3",
|
||||
"token": token,
|
||||
}
|
||||
event_cluster_matched = UserRouterCluster.get_event_cluster("UserList").match_event(event_key=event_key)
|
||||
response.headers["X-Header"] = "Test Header GET"
|
||||
if runner_callable := event_cluster_matched.event_callable():
|
||||
return runner_callable
|
||||
raise ValueError("Event key not found or multiple matches found")
|
||||
|
||||
|
||||
@user_route.post(
|
||||
path="/create",
|
||||
description="Create users endpoint",
|
||||
operation_id="08d4b572-1584-47bb-aa42-8d068e5514e7",
|
||||
)
|
||||
def user_create_route(
|
||||
request: Request,
|
||||
response: Response,
|
||||
language: str = Header(None, alias="language"),
|
||||
domain: str = Header(None, alias="domain"),
|
||||
tz: str = Header(None, alias="timezone"),
|
||||
):
|
||||
"""
|
||||
Create users endpoint
|
||||
"""
|
||||
endpoint_code = "08d4b572-1584-47bb-aa42-8d068e5514e7"
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
token_object = TokenProvider.get_dict_from_redis(token=token)
|
||||
event_key = TokenProvider.retrieve_event_codes(
|
||||
endpoint_code=endpoint_code, token=token_object
|
||||
)
|
||||
headers = {
|
||||
"language": language or "",
|
||||
"domain": domain or "",
|
||||
"eys-ext": f"{str(uuid.uuid4())}",
|
||||
"tz": tz or "GMT+3",
|
||||
"token": token,
|
||||
}
|
||||
event_cluster_matched = UserRouterCluster.get_event_cluster("UserCreate").match_event(event_key=event_key)
|
||||
response.headers["X-Header"] = "Test Header POST"
|
||||
if runner_callable := event_cluster_matched.event_callable():
|
||||
return runner_callable
|
||||
raise ValueError("Event key not found or multiple matches found")
|
||||
|
||||
|
||||
@user_route.post(
|
||||
path="/update",
|
||||
description="Update users endpoint",
|
||||
operation_id="b641236a-928d-4f19-a1d2-5edf611d1e56",
|
||||
)
|
||||
def user_update_route(request: Request, response: Response):
|
||||
"""
|
||||
Update users endpoint
|
||||
"""
|
||||
endpoint_code = "b641236a-928d-4f19-a1d2-5edf611d1e56"
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
token_object = TokenProvider.get_dict_from_redis(token=token)
|
||||
event_key = TokenProvider.retrieve_event_codes(
|
||||
endpoint_code=endpoint_code, token=token_object
|
||||
)
|
||||
headers = {
|
||||
"language": language or "",
|
||||
"domain": domain or "",
|
||||
"eys-ext": f"{str(uuid.uuid4())}",
|
||||
"tz": tz or "GMT+3",
|
||||
"token": token,
|
||||
}
|
||||
event_cluster_matched = UserRouterCluster.get_event_cluster("UserUpdate").match_event(event_key=event_key)
|
||||
response.headers["X-Header"] = "Test Header POST"
|
||||
if runner_callable := event_cluster_matched.event_callable():
|
||||
return runner_callable
|
||||
raise ValueError("Event key not found or multiple matches found")
|
||||
8
ApiServices/IdentityService/Events/__init__.py
Normal file
8
ApiServices/IdentityService/Events/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from .people.cluster import PeopleRouterCluster
|
||||
from .user.cluster import UserRouterCluster
|
||||
|
||||
|
||||
__all__ = [
|
||||
"PeopleRouterCluster",
|
||||
"UserRouterCluster",
|
||||
]
|
||||
32
ApiServices/IdentityService/Events/people/cluster.py
Normal file
32
ApiServices/IdentityService/Events/people/cluster.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from ApiControllers.abstracts.event_clusters import EventCluster, RouterCluster
|
||||
from .supers_events import (
|
||||
SupersPeopleCreateEvent,
|
||||
SupersPeopleUpdateEvent,
|
||||
SupersPeopleListEvent
|
||||
)
|
||||
|
||||
PeopleRouterCluster = RouterCluster(
|
||||
name="PeopleRouterCluster"
|
||||
)
|
||||
|
||||
PeopleEventClusterList = EventCluster(
|
||||
name="PeopleList",
|
||||
endpoint_uu_id="f102db46-031a-43e4-966a-dae6896f985b"
|
||||
)
|
||||
PeopleEventClusterList.add_event(SupersPeopleListEvent)
|
||||
PeopleEventClusterCreate = EventCluster(
|
||||
name="PeopleCreate",
|
||||
endpoint_uu_id="eb465fde-337f-4b81-94cf-28c6d4f2b1b6"
|
||||
)
|
||||
PeopleEventClusterCreate.add_event(SupersPeopleCreateEvent)
|
||||
PeopleEventClusterUpdate = EventCluster(
|
||||
name="PeopleUpdate",
|
||||
endpoint_uu_id="c9e5ba69-6915-43f5-8f9c-a5c2aa865b89"
|
||||
)
|
||||
PeopleEventClusterUpdate.add_event(SupersPeopleUpdateEvent)
|
||||
|
||||
PeopleRouterCluster.set_event_cluster(PeopleEventClusterList)
|
||||
PeopleRouterCluster.set_event_cluster(PeopleEventClusterCreate)
|
||||
PeopleRouterCluster.set_event_cluster(PeopleEventClusterUpdate)
|
||||
|
||||
|
||||
@@ -1,21 +1,38 @@
|
||||
from ApiServices.IdentityService.initializer.event_clusters import EventCluster, Event
|
||||
from ApiServices.IdentityService.validations.people.validations import (
|
||||
from ApiControllers.abstracts.event_clusters import Event
|
||||
from Validations.people.validations import (
|
||||
REQUESTAWMXNTKMGPPOJWRCTZUBADNFLQDBDYVQAORFAVCSXUUHEBQHCEPCSKFBADBODFDBPYKOVINV,
|
||||
)
|
||||
from Controllers.Postgres.pagination import Pagination, PaginationResult, PaginateOnly
|
||||
from Controllers.Postgres.response import EndpointResponse
|
||||
from Schemas.identity.identity import People
|
||||
from Schemas import People
|
||||
|
||||
|
||||
# Create endpoint
|
||||
supers_people_create = Event(
|
||||
name="supers_people_list",
|
||||
SupersPeopleCreateEvent = Event(
|
||||
name="supers_people_create",
|
||||
key="ec4c2404-a61b-46c7-bbdf-ce3357e6cf41",
|
||||
request_validator=None, # TODO: Add request validator
|
||||
response_validator=None, # TODO: Add response validator
|
||||
description="Create events of people endpoint",
|
||||
)
|
||||
|
||||
# Update endpoint
|
||||
SupersPeopleUpdateEvent = Event(
|
||||
name="supers_people_update",
|
||||
key="91e77de4-9f29-4309-b121-4aad256d440c",
|
||||
request_validator=None, # TODO: Add request validator
|
||||
response_validator=None, # TODO: Add response validator
|
||||
description="Update events of people endpoint",
|
||||
)
|
||||
|
||||
# List endpoint
|
||||
SupersPeopleListEvent = Event(
|
||||
name="supers_people_list",
|
||||
key="6828d280-e587-400d-a622-c318277386c3",
|
||||
request_validator=None, # TODO: Add request validator
|
||||
response_validator=None, # TODO: Add response validator
|
||||
description="List events of people endpoint",
|
||||
)
|
||||
|
||||
|
||||
def supers_people_create_callable(list_options):
|
||||
"""
|
||||
@@ -32,21 +49,7 @@ def supers_people_create_callable(list_options):
|
||||
}
|
||||
|
||||
|
||||
supers_people_create.event_callable = supers_people_create_callable
|
||||
|
||||
people_event_cluster_create = EventCluster(
|
||||
endpoint_uu_id="eb465fde-337f-4b81-94cf-28c6d4f2b1b6"
|
||||
)
|
||||
people_event_cluster_create.add_event([supers_people_create])
|
||||
|
||||
# Update endpoint
|
||||
supers_people_update = Event(
|
||||
name="supers_people_update",
|
||||
key="91e77de4-9f29-4309-b121-4aad256d440c",
|
||||
request_validator=None, # TODO: Add request validator
|
||||
response_validator=None, # TODO: Add response validator
|
||||
description="Update events of people endpoint",
|
||||
)
|
||||
SupersPeopleCreateEvent.event_callable = supers_people_create_callable
|
||||
|
||||
|
||||
def supers_people_update_callable():
|
||||
@@ -64,21 +67,7 @@ def supers_people_update_callable():
|
||||
}
|
||||
|
||||
|
||||
supers_people_update.event_callable = supers_people_update_callable
|
||||
people_event_cluster_update = EventCluster(
|
||||
endpoint_uu_id="c9e5ba69-6915-43f5-8f9c-a5c2aa865b89"
|
||||
)
|
||||
people_event_cluster_update.add_event([supers_people_update])
|
||||
|
||||
|
||||
# List endpoint
|
||||
supers_people_list = Event(
|
||||
name="supers_people_list",
|
||||
key="6828d280-e587-400d-a622-c318277386c3",
|
||||
request_validator=None, # TODO: Add request validator
|
||||
response_validator=None, # TODO: Add response validator
|
||||
description="List events of people endpoint",
|
||||
)
|
||||
SupersPeopleUpdateEvent.event_callable = supers_people_update_callable
|
||||
|
||||
|
||||
def supers_people_list_callable(list_options: PaginateOnly):
|
||||
@@ -87,10 +76,6 @@ def supers_people_list_callable(list_options: PaginateOnly):
|
||||
"""
|
||||
list_options = PaginateOnly(**list_options.model_dump())
|
||||
with People.new_session() as db_session:
|
||||
People.pre_query = People.filter_all(
|
||||
People.firstname.ilike("%B%"), db=db_session
|
||||
).query
|
||||
|
||||
if list_options.query:
|
||||
people_list = People.filter_all(
|
||||
*People.convert(list_options.query), db=db_session
|
||||
@@ -110,19 +95,4 @@ def supers_people_list_callable(list_options: PaginateOnly):
|
||||
).response
|
||||
|
||||
|
||||
supers_people_list.event_callable = supers_people_list_callable
|
||||
people_event_cluster_list = EventCluster(
|
||||
endpoint_uu_id="f102db46-031a-43e4-966a-dae6896f985b"
|
||||
)
|
||||
|
||||
people_event_cluster_list.add_event([supers_people_list])
|
||||
|
||||
|
||||
class PeopleCluster:
|
||||
"""
|
||||
People Clusters
|
||||
"""
|
||||
|
||||
PeopleListCluster = people_event_cluster_list
|
||||
PeopleCreateCluster = people_event_cluster_create
|
||||
PeopleUpdateCluster = people_event_cluster_update
|
||||
SupersPeopleListEvent.event_callable = supers_people_list_callable
|
||||
32
ApiServices/IdentityService/Events/user/cluster.py
Normal file
32
ApiServices/IdentityService/Events/user/cluster.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from ApiControllers.abstracts.event_clusters import EventCluster, RouterCluster
|
||||
from .supers_events import (
|
||||
SuperUsersListEvent,
|
||||
SuperUsersCreateEvent,
|
||||
SuperUsersUpdateEvent,
|
||||
)
|
||||
|
||||
UserRouterCluster = RouterCluster(
|
||||
name="UserRouterCluster"
|
||||
)
|
||||
|
||||
UserEventClusterList = EventCluster(
|
||||
name="UserList",
|
||||
endpoint_uu_id="5bc09312-d3f2-4f47-baba-17c928706da8"
|
||||
)
|
||||
UserEventClusterList.add_event(SuperUsersListEvent)
|
||||
|
||||
UserEventClusterCreate = EventCluster(
|
||||
name="UserCreate",
|
||||
endpoint_uu_id="08d4b572-1584-47bb-aa42-8d068e5514e7"
|
||||
)
|
||||
UserEventClusterCreate.add_event(SuperUsersCreateEvent)
|
||||
|
||||
UserEventClusterUpdate = EventCluster(
|
||||
name="UserUpdate",
|
||||
endpoint_uu_id="b641236a-928d-4f19-a1d2-5edf611d1e56"
|
||||
)
|
||||
UserEventClusterUpdate.add_event(SuperUsersUpdateEvent)
|
||||
|
||||
UserRouterCluster.set_event_cluster(UserEventClusterList)
|
||||
UserRouterCluster.set_event_cluster(UserEventClusterCreate)
|
||||
UserRouterCluster.set_event_cluster(UserEventClusterUpdate)
|
||||
99
ApiServices/IdentityService/Events/user/supers_events.py
Normal file
99
ApiServices/IdentityService/Events/user/supers_events.py
Normal file
@@ -0,0 +1,99 @@
|
||||
from ApiControllers.abstracts.event_clusters import Event
|
||||
from Controllers.Postgres.pagination import Pagination, PaginationResult, PaginateOnly
|
||||
from Controllers.Postgres.response import EndpointResponse
|
||||
from Schemas import (
|
||||
Users,
|
||||
)
|
||||
|
||||
SuperUsersListEvent = Event(
|
||||
name="supers_users_list",
|
||||
key="341b394f-9f11-4abb-99e7-4b27fa6bf012",
|
||||
request_validator=None, # TODO: Add request validator
|
||||
response_validator=None, # TODO: Add response validator
|
||||
description="List events of users endpoint",
|
||||
)
|
||||
|
||||
|
||||
def supers_users_list_callable(list_options: PaginateOnly):
|
||||
"""
|
||||
Example callable method
|
||||
"""
|
||||
list_options = PaginateOnly(**list_options.model_dump())
|
||||
with Users.new_session() as db_session:
|
||||
if list_options.query:
|
||||
users_list = Users.filter_all(
|
||||
*Users.convert(list_options.query), db=db_session
|
||||
)
|
||||
else:
|
||||
users_list = Users.filter_all(db=db_session)
|
||||
pagination = Pagination(data=users_list)
|
||||
pagination.change(**list_options.model_dump())
|
||||
pagination_result = PaginationResult(
|
||||
data=users_list,
|
||||
pagination=pagination,
|
||||
# response_model="",
|
||||
)
|
||||
return EndpointResponse(
|
||||
message="MSG0003-LIST",
|
||||
pagination_result=pagination_result,
|
||||
).response
|
||||
# return {
|
||||
# "completed": True,
|
||||
# "message": "Example callable method 2",
|
||||
# "info": {
|
||||
# "host": "example_host",
|
||||
# "user_agent": "example_user_agent",
|
||||
# },
|
||||
# }
|
||||
|
||||
|
||||
SuperUsersListEvent.event_callable = supers_users_list_callable
|
||||
|
||||
SuperUsersCreateEvent = Event(
|
||||
name="supers_users_create",
|
||||
key="4e7e189e-e015-4ff8-902d-60138cbc77a6",
|
||||
request_validator=None, # TODO: Add request validator
|
||||
response_validator=None, # TODO: Add response validator
|
||||
description="Create events of users endpoint",
|
||||
)
|
||||
|
||||
|
||||
def supers_users_create_callable():
|
||||
"""
|
||||
Example callable method
|
||||
"""
|
||||
return {
|
||||
"completed": True,
|
||||
"message": "Example callable method 2",
|
||||
"info": {
|
||||
"host": "example_host",
|
||||
"user_agent": "example_user_agent",
|
||||
},
|
||||
}
|
||||
|
||||
SuperUsersCreateEvent.event_callable = supers_users_create_callable
|
||||
|
||||
# Update endpoint
|
||||
SuperUsersUpdateEvent = Event(
|
||||
name="supers_users_update",
|
||||
key="efa4aa4a-d414-4391-91ee-97eb617b7755",
|
||||
request_validator=None, # TODO: Add request validator
|
||||
response_validator=None, # TODO: Add response validator
|
||||
description="Update events of users endpoint",
|
||||
)
|
||||
|
||||
|
||||
def supers_users_update_callable():
|
||||
"""
|
||||
Example callable method
|
||||
"""
|
||||
return {
|
||||
"completed": True,
|
||||
"message": "Example callable method 2",
|
||||
"info": {
|
||||
"host": "example_host",
|
||||
"user_agent": "example_user_agent",
|
||||
},
|
||||
}
|
||||
|
||||
SuperUsersUpdateEvent.event_callable = supers_users_update_callable
|
||||
@@ -0,0 +1,24 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class REQUESTAWMXNTKMGPPOJWRCTZUBADNFLQDBDYVQAORFAVCSXUUHEBQHCEPCSKFBADBODFDBPYKOVINV(
|
||||
BaseModel
|
||||
):
|
||||
uu_id: str
|
||||
created_at: str
|
||||
updated_at: str
|
||||
person_tag: str
|
||||
expiry_starts: str
|
||||
expiry_ends: str
|
||||
firstname: str
|
||||
middle_name: str
|
||||
surname: str
|
||||
birth_date: str
|
||||
birth_place: str
|
||||
sex_code: str
|
||||
country_code: str
|
||||
tax_no: str
|
||||
active: bool
|
||||
deleted: bool
|
||||
is_confirmed: bool
|
||||
is_notification_send: bool
|
||||
@@ -1,16 +0,0 @@
|
||||
import uvicorn
|
||||
|
||||
from config import api_config
|
||||
from create_app import create_app
|
||||
|
||||
# from prometheus_fastapi_instrumentator import Instrumentator
|
||||
|
||||
|
||||
app = create_app() # Create FastAPI application
|
||||
# Instrumentator().instrument(app=app).expose(app=app) # Setup Prometheus metrics
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run the application with Uvicorn Server
|
||||
uvicorn_config = uvicorn.Config(**api_config.app_as_dict)
|
||||
uvicorn.Server(uvicorn_config).run()
|
||||
@@ -1,64 +0,0 @@
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
|
||||
class Configs(BaseSettings):
|
||||
"""
|
||||
ApiTemplate configuration settings.
|
||||
"""
|
||||
|
||||
PATH: str = ""
|
||||
HOST: str = ""
|
||||
PORT: int = 0
|
||||
LOG_LEVEL: str = "info"
|
||||
RELOAD: int = 0
|
||||
ACCESS_TOKEN_TAG: str = ""
|
||||
|
||||
ACCESS_EMAIL_EXT: str = ""
|
||||
TITLE: str = ""
|
||||
ALGORITHM: str = ""
|
||||
ACCESS_TOKEN_LENGTH: int = 90
|
||||
REFRESHER_TOKEN_LENGTH: int = 144
|
||||
EMAIL_HOST: str = ""
|
||||
DATETIME_FORMAT: str = ""
|
||||
FORGOT_LINK: str = ""
|
||||
ALLOW_ORIGINS: list = ["http://localhost:3000"]
|
||||
VERSION: str = "0.1.001"
|
||||
DESCRIPTION: str = ""
|
||||
|
||||
@property
|
||||
def app_as_dict(self) -> dict:
|
||||
"""
|
||||
Convert the settings to a dictionary.
|
||||
"""
|
||||
return {
|
||||
"app": self.PATH,
|
||||
"host": self.HOST,
|
||||
"port": int(self.PORT),
|
||||
"log_level": self.LOG_LEVEL,
|
||||
"reload": bool(self.RELOAD),
|
||||
}
|
||||
|
||||
@property
|
||||
def api_info(self):
|
||||
"""
|
||||
Returns a dictionary with application information.
|
||||
"""
|
||||
return {
|
||||
"title": self.TITLE,
|
||||
"description": self.DESCRIPTION,
|
||||
"default_response_class": JSONResponse,
|
||||
"version": self.VERSION,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def forgot_link(cls, forgot_key):
|
||||
"""
|
||||
Generate a forgot password link.
|
||||
"""
|
||||
return cls.FORGOT_LINK + forgot_key
|
||||
|
||||
model_config = SettingsConfigDict(env_prefix="API_")
|
||||
|
||||
|
||||
api_config = Configs()
|
||||
@@ -1,49 +0,0 @@
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import RedirectResponse
|
||||
|
||||
from endpoints.routes import get_routes
|
||||
from open_api_creator import create_openapi_schema
|
||||
from middlewares.token_middleware import token_middleware
|
||||
from initializer.create_route import RouteRegisterController
|
||||
|
||||
from config import api_config
|
||||
|
||||
|
||||
def create_events_if_any_cluster_set():
|
||||
import events
|
||||
|
||||
for event_str in events.__all__:
|
||||
if to_set_events := getattr(events, event_str, None):
|
||||
to_set_events.set_events_to_database()
|
||||
|
||||
|
||||
def create_app():
|
||||
|
||||
application = FastAPI(**api_config.api_info)
|
||||
# application.mount(
|
||||
# "/application/static",
|
||||
# StaticFiles(directory="application/static"),
|
||||
# name="static",
|
||||
# )
|
||||
application.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=api_config.ALLOW_ORIGINS,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
@application.middleware("http")
|
||||
async def add_token_middleware(request: Request, call_next):
|
||||
return await token_middleware(request, call_next)
|
||||
|
||||
@application.get("/", description="Redirect Route", include_in_schema=False)
|
||||
async def redirect_to_docs():
|
||||
return RedirectResponse(url="/docs")
|
||||
|
||||
route_register = RouteRegisterController(app=application, router_list=get_routes())
|
||||
application = route_register.register_routes()
|
||||
create_events_if_any_cluster_set()
|
||||
application.openapi = lambda _=application: create_openapi_schema(_)
|
||||
return application
|
||||
@@ -1,90 +0,0 @@
|
||||
import uuid
|
||||
|
||||
from fastapi import APIRouter, Request, Response, Header
|
||||
|
||||
from ApiServices.IdentityService.config import api_config
|
||||
from ApiServices.IdentityService.events.user.event import supers_users_list
|
||||
|
||||
|
||||
user_route = APIRouter(prefix="/user", tags=["User"])
|
||||
|
||||
|
||||
@user_route.post(
|
||||
path="/list",
|
||||
description="Test Template Route",
|
||||
operation_id="5bc09312-d3f2-4f47-baba-17c928706da8",
|
||||
)
|
||||
def test_template(
|
||||
request: Request,
|
||||
response: Response,
|
||||
language: str = Header(None, alias="language"),
|
||||
domain: str = Header(None, alias="domain"),
|
||||
tz: str = Header(None, alias="timezone"),
|
||||
):
|
||||
"""
|
||||
Test Template Route
|
||||
"""
|
||||
event_code = "bb20c8c6-a289-4cab-9da7-34ca8a36c8e5"
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
headers = {
|
||||
"language": language or "",
|
||||
"domain": domain or "",
|
||||
"eys-ext": f"{str(uuid.uuid4())}",
|
||||
"tz": tz or "GMT+3",
|
||||
"token": token,
|
||||
}
|
||||
event_cluster_matched = supers_users_list.match_event(
|
||||
event_keys=[
|
||||
"3f510dcf-9f84-4eb9-b919-f582f30adab1",
|
||||
"9f403034-deba-4e1f-b43e-b25d3c808d39",
|
||||
"b8ec6e64-286a-4f60-8554-7a3865454944",
|
||||
]
|
||||
)
|
||||
response.headers["X-Header"] = "Test Header GET"
|
||||
if runner_callable := event_cluster_matched.example_callable():
|
||||
return runner_callable
|
||||
raise ValueError("Event key not found or multiple matches found")
|
||||
|
||||
|
||||
@user_route.post(
|
||||
path="/create",
|
||||
description="Test Template Route with Post Method",
|
||||
operation_id="08d4b572-1584-47bb-aa42-8d068e5514e7",
|
||||
)
|
||||
def test_template_post(request: Request, response: Response):
|
||||
"""
|
||||
Test Template Route with Post Method
|
||||
"""
|
||||
event_cluster_matched = supers_users_list.match_event(
|
||||
event_keys=[
|
||||
"3f510dcf-9f84-4eb9-b919-f582f30adab1",
|
||||
"9f403034-deba-4e1f-b43e-b25d3c808d39",
|
||||
"b8ec6e64-286a-4f60-8554-7a3865454944",
|
||||
]
|
||||
)
|
||||
response.headers["X-Header"] = "Test Header POST"
|
||||
if runner_callable := event_cluster_matched.example_callable():
|
||||
return runner_callable
|
||||
raise ValueError("Event key not found or multiple matches found")
|
||||
|
||||
|
||||
@user_route.post(
|
||||
path="/update",
|
||||
description="Test Template Route with Post Method",
|
||||
operation_id="b641236a-928d-4f19-a1d2-5edf611d1e56",
|
||||
)
|
||||
def test_template_post(request: Request, response: Response):
|
||||
"""
|
||||
Test Template Route with Post Method
|
||||
"""
|
||||
event_cluster_matched = supers_users_list.match_event(
|
||||
event_keys=[
|
||||
"3f510dcf-9f84-4eb9-b919-f582f30adab1",
|
||||
"9f403034-deba-4e1f-b43e-b25d3c808d39",
|
||||
"b8ec6e64-286a-4f60-8554-7a3865454944",
|
||||
]
|
||||
)
|
||||
response.headers["X-Header"] = "Test Header POST"
|
||||
if runner_callable := event_cluster_matched.example_callable():
|
||||
return runner_callable
|
||||
raise ValueError("Event key not found or multiple matches found")
|
||||
@@ -1,12 +0,0 @@
|
||||
from .people.event import (
|
||||
people_event_cluster_list,
|
||||
people_event_cluster_update,
|
||||
people_event_cluster_create,
|
||||
)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"people_event_cluster_list",
|
||||
"people_event_cluster_update",
|
||||
"people_event_cluster_create",
|
||||
]
|
||||
@@ -1,33 +0,0 @@
|
||||
from ApiServices.IdentityService.initializer.event_clusters import EventCluster, Event
|
||||
|
||||
|
||||
supers_users_list = Event(
|
||||
name="supers_people_list",
|
||||
key="341b394f-9f11-4abb-99e7-4b27fa6bf012",
|
||||
request_validator=None, # TODO: Add request validator
|
||||
response_validator=None, # TODO: Add response validator
|
||||
description="Example event description",
|
||||
)
|
||||
|
||||
|
||||
def supers_people_list_callable():
|
||||
"""
|
||||
Example callable method
|
||||
"""
|
||||
return {
|
||||
"completed": True,
|
||||
"message": "Example callable method 2",
|
||||
"info": {
|
||||
"host": "example_host",
|
||||
"user_agent": "example_user_agent",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
supers_users_list.event_callable = supers_people_list_callable
|
||||
|
||||
people_event_cluster_list = EventCluster(
|
||||
endpoint_uu_id="f102db46-031a-43e4-966a-dae6896f985b"
|
||||
)
|
||||
|
||||
people_event_cluster_list.add_event([supers_users_list])
|
||||
@@ -1,42 +0,0 @@
|
||||
from typing import List
|
||||
from fastapi import APIRouter, FastAPI
|
||||
|
||||
|
||||
class RouteRegisterController:
|
||||
|
||||
def __init__(self, app: FastAPI, router_list: List[APIRouter]):
|
||||
self.router_list = router_list
|
||||
self.app = app
|
||||
|
||||
@staticmethod
|
||||
def add_router_with_event_to_database(router: APIRouter):
|
||||
from Schemas import EndpointRestriction
|
||||
|
||||
with EndpointRestriction.new_session() as db_session:
|
||||
for route in router.routes:
|
||||
route_path = str(getattr(route, "path"))
|
||||
route_summary = str(getattr(route, "name"))
|
||||
operation_id = getattr(route, "operation_id", None)
|
||||
if not operation_id:
|
||||
continue
|
||||
|
||||
for route_method in [
|
||||
method.lower() for method in getattr(route, "methods")
|
||||
]:
|
||||
restriction = EndpointRestriction.find_or_create(
|
||||
endpoint_method=route_method,
|
||||
endpoint_name=route_path,
|
||||
endpoint_desc=route_summary.replace("_", " "),
|
||||
endpoint_function=route_summary,
|
||||
operation_uu_id=operation_id, # UUID of the endpoint
|
||||
is_confirmed=True,
|
||||
db=db_session,
|
||||
)
|
||||
if restriction.meta_data.created:
|
||||
restriction.save(db=db_session)
|
||||
|
||||
def register_routes(self):
|
||||
for router in self.router_list:
|
||||
self.app.include_router(router)
|
||||
self.add_router_with_event_to_database(router)
|
||||
return self.app
|
||||
@@ -1,91 +0,0 @@
|
||||
from typing import Optional, Type
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class EventCluster:
|
||||
|
||||
def __init__(self, endpoint_uu_id: str):
|
||||
self.endpoint_uu_id = endpoint_uu_id
|
||||
self.events = []
|
||||
|
||||
def add_event(self, list_of_events: list["Event"]):
|
||||
"""
|
||||
Add an event to the cluster
|
||||
"""
|
||||
for event in list_of_events:
|
||||
self.events.append(event)
|
||||
self.events = list(set(self.events))
|
||||
|
||||
def get_event(self, event_key: str):
|
||||
"""
|
||||
Get an event by its key
|
||||
"""
|
||||
|
||||
for event in self.events:
|
||||
if event.key == event_key:
|
||||
return event
|
||||
return None
|
||||
|
||||
def set_events_to_database(self):
|
||||
from Schemas import Events, EndpointRestriction
|
||||
|
||||
with Events.new_session() as db_session:
|
||||
if to_save_endpoint := EndpointRestriction.filter_one(
|
||||
EndpointRestriction.operation_uu_id == self.endpoint_uu_id,
|
||||
db=db_session,
|
||||
).data:
|
||||
for event in self.events:
|
||||
event_to_save_database = Events.find_or_create(
|
||||
function_code=event.key,
|
||||
function_class=event.name,
|
||||
description=event.description,
|
||||
endpoint_code=self.endpoint_uu_id,
|
||||
endpoint_id=to_save_endpoint.id,
|
||||
endpoint_uu_id=str(to_save_endpoint.uu_id),
|
||||
is_confirmed=True,
|
||||
active=True,
|
||||
db=db_session,
|
||||
)
|
||||
if event_to_save_database.meta_data.created:
|
||||
event_to_save_database.save(db=db_session)
|
||||
print(
|
||||
f"UUID: {event_to_save_database.uu_id} event is saved to {to_save_endpoint.uu_id}"
|
||||
)
|
||||
|
||||
def match_event(self, event_key: str) -> "Event":
|
||||
"""
|
||||
Match an event by its key
|
||||
"""
|
||||
# print('set(event_keys)', set(event_keys))
|
||||
# print('event.keys', set([event.key for event in self.events]))
|
||||
# intersection_of_key: set[str] = set(event_key) & set([event.key for event in self.events])
|
||||
# if not len(intersection_of_key) == 1:
|
||||
# raise ValueError(
|
||||
# f"Event key not found or multiple matches found: {intersection_of_key}"
|
||||
# )
|
||||
return self.get_event(event_key=event_key)
|
||||
|
||||
|
||||
class Event:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
key: str,
|
||||
request_validator: Optional[Type[BaseModel]] = None,
|
||||
response_validator: Optional[Type[BaseModel]] = None,
|
||||
description: str = "",
|
||||
):
|
||||
self.name = name
|
||||
self.key = key
|
||||
self.request_validator = request_validator
|
||||
self.response_validator = response_validator
|
||||
self.description = description
|
||||
|
||||
def event_callable(self):
|
||||
"""
|
||||
Example callable method
|
||||
"""
|
||||
print(self.name)
|
||||
return {}
|
||||
@@ -1,24 +0,0 @@
|
||||
from fastapi import Request, status
|
||||
from fastapi.responses import JSONResponse
|
||||
from ApiServices.IdentityService.endpoints.routes import get_safe_endpoint_urls
|
||||
from ApiServices.IdentityService.config import api_config
|
||||
|
||||
|
||||
async def token_middleware(request: Request, call_next):
|
||||
|
||||
base_url = request.url.path
|
||||
safe_endpoints = [_[0] for _ in get_safe_endpoint_urls()]
|
||||
if base_url in safe_endpoints:
|
||||
return await call_next(request)
|
||||
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
if not token:
|
||||
return JSONResponse(
|
||||
content={
|
||||
"error": "EYS_0002",
|
||||
},
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
)
|
||||
|
||||
response = await call_next(request)
|
||||
return response
|
||||
@@ -1,116 +0,0 @@
|
||||
from typing import Any, Dict
|
||||
from fastapi import FastAPI
|
||||
from fastapi.routing import APIRoute
|
||||
from fastapi.openapi.utils import get_openapi
|
||||
|
||||
from config import api_config as template_api_config
|
||||
from endpoints.routes import get_safe_endpoint_urls
|
||||
|
||||
|
||||
class OpenAPISchemaCreator:
|
||||
"""
|
||||
OpenAPI schema creator and customizer for FastAPI applications.
|
||||
"""
|
||||
|
||||
def __init__(self, app: FastAPI):
|
||||
"""
|
||||
Initialize the OpenAPI schema creator.
|
||||
|
||||
Args:
|
||||
app: FastAPI application instance
|
||||
"""
|
||||
self.app = app
|
||||
self.safe_endpoint_list: list[tuple[str, str]] = get_safe_endpoint_urls()
|
||||
self.routers_list = self.app.routes
|
||||
|
||||
@staticmethod
|
||||
def create_security_schemes() -> Dict[str, Any]:
|
||||
"""
|
||||
Create security scheme definitions.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: Security scheme configurations
|
||||
"""
|
||||
|
||||
return {
|
||||
"BearerAuth": {
|
||||
"type": "apiKey",
|
||||
"in": "header",
|
||||
"name": template_api_config.ACCESS_TOKEN_TAG,
|
||||
"description": "Enter: **'Bearer <JWT>'**, where JWT is the access token",
|
||||
}
|
||||
}
|
||||
|
||||
def configure_route_security(
|
||||
self, path: str, method: str, schema: Dict[str, Any]
|
||||
) -> None:
|
||||
"""
|
||||
Configure security requirements for a specific route.
|
||||
|
||||
Args:
|
||||
path: Route path
|
||||
method: HTTP method
|
||||
schema: OpenAPI schema to modify
|
||||
"""
|
||||
if not schema.get("paths", {}).get(path, {}).get(method):
|
||||
return
|
||||
|
||||
# Check if endpoint is in safe list
|
||||
endpoint_path = f"{path}:{method}"
|
||||
list_of_safe_endpoints = [
|
||||
f"{e[0]}:{str(e[1]).lower()}" for e in self.safe_endpoint_list
|
||||
]
|
||||
if endpoint_path not in list_of_safe_endpoints:
|
||||
if "security" not in schema["paths"][path][method]:
|
||||
schema["paths"][path][method]["security"] = []
|
||||
schema["paths"][path][method]["security"].append({"BearerAuth": []})
|
||||
|
||||
def create_schema(self) -> Dict[str, Any]:
|
||||
"""
|
||||
Create the complete OpenAPI schema.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: Complete OpenAPI schema
|
||||
"""
|
||||
openapi_schema = get_openapi(
|
||||
title=template_api_config.TITLE,
|
||||
description=template_api_config.DESCRIPTION,
|
||||
version=template_api_config.VERSION,
|
||||
routes=self.app.routes,
|
||||
)
|
||||
|
||||
# Add security schemes
|
||||
if "components" not in openapi_schema:
|
||||
openapi_schema["components"] = {}
|
||||
|
||||
openapi_schema["components"]["securitySchemes"] = self.create_security_schemes()
|
||||
|
||||
# Configure route security and responses
|
||||
for route in self.app.routes:
|
||||
if isinstance(route, APIRoute) and route.include_in_schema:
|
||||
path = str(route.path)
|
||||
methods = [method.lower() for method in route.methods]
|
||||
for method in methods:
|
||||
self.configure_route_security(path, method, openapi_schema)
|
||||
|
||||
# Add custom documentation extensions
|
||||
openapi_schema["x-documentation"] = {
|
||||
"postman_collection": "/docs/postman",
|
||||
"swagger_ui": "/docs",
|
||||
"redoc": "/redoc",
|
||||
}
|
||||
return openapi_schema
|
||||
|
||||
|
||||
def create_openapi_schema(app: FastAPI) -> Dict[str, Any]:
|
||||
"""
|
||||
Create OpenAPI schema for a FastAPI application.
|
||||
|
||||
Args:
|
||||
app: FastAPI application instance
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: Complete OpenAPI schema
|
||||
"""
|
||||
creator = OpenAPISchemaCreator(app)
|
||||
return creator.create_schema()
|
||||
@@ -1,206 +0,0 @@
|
||||
import enum
|
||||
|
||||
from typing import Optional, Union, Dict, Any, List
|
||||
from pydantic import BaseModel
|
||||
from Controllers.Redis.database import RedisActions
|
||||
|
||||
|
||||
class UserType(enum.Enum):
|
||||
|
||||
employee = 1
|
||||
occupant = 2
|
||||
|
||||
|
||||
class Credentials(BaseModel):
|
||||
|
||||
person_id: int
|
||||
person_name: str
|
||||
|
||||
|
||||
class ApplicationToken(BaseModel):
|
||||
# Application Token Object -> is the main object for the user
|
||||
|
||||
user_type: int = UserType.occupant.value
|
||||
credential_token: str = ""
|
||||
|
||||
user_uu_id: str
|
||||
user_id: int
|
||||
|
||||
person_id: int
|
||||
person_uu_id: str
|
||||
|
||||
request: Optional[dict] = None # Request Info of Client
|
||||
expires_at: Optional[float] = None # Expiry timestamp
|
||||
|
||||
|
||||
class OccupantToken(BaseModel):
|
||||
|
||||
# Selection of the occupant type for a build part is made by the user
|
||||
|
||||
living_space_id: int # Internal use
|
||||
living_space_uu_id: str # Outer use
|
||||
|
||||
occupant_type_id: int
|
||||
occupant_type_uu_id: str
|
||||
occupant_type: str
|
||||
|
||||
build_id: int
|
||||
build_uuid: str
|
||||
build_part_id: int
|
||||
build_part_uuid: str
|
||||
|
||||
responsible_company_id: Optional[int] = None
|
||||
responsible_company_uuid: Optional[str] = None
|
||||
responsible_employee_id: Optional[int] = None
|
||||
responsible_employee_uuid: Optional[str] = None
|
||||
|
||||
# ID list of reachable event codes as "endpoint_code": ["UUID", "UUID"]
|
||||
reachable_event_codes: Optional[dict[str, str]] = None
|
||||
|
||||
# ID list of reachable applications as "page_url": ["UUID", "UUID"]
|
||||
reachable_app_codes: Optional[dict[str, str]] = None
|
||||
|
||||
|
||||
class CompanyToken(BaseModel):
|
||||
|
||||
# Selection of the company for an employee is made by the user
|
||||
company_id: int
|
||||
company_uu_id: str
|
||||
|
||||
department_id: int # ID list of departments
|
||||
department_uu_id: str # ID list of departments
|
||||
|
||||
duty_id: int
|
||||
duty_uu_id: str
|
||||
|
||||
staff_id: int
|
||||
staff_uu_id: str
|
||||
|
||||
employee_id: int
|
||||
employee_uu_id: str
|
||||
bulk_duties_id: int
|
||||
|
||||
# ID list of reachable event codes as "endpoint_code": ["UUID", "UUID"]
|
||||
reachable_event_codes: Optional[dict[str, str]] = None
|
||||
|
||||
# ID list of reachable applications as "page_url": ["UUID", "UUID"]
|
||||
reachable_app_codes: Optional[dict[str, str]] = None
|
||||
|
||||
|
||||
class OccupantTokenObject(ApplicationToken):
|
||||
# Occupant Token Object -> Requires selection of the occupant type for a specific build part
|
||||
|
||||
available_occupants: dict = None
|
||||
selected_occupant: Optional[OccupantToken] = None # Selected Occupant Type
|
||||
|
||||
@property
|
||||
def is_employee(self) -> bool:
|
||||
return False
|
||||
|
||||
@property
|
||||
def is_occupant(self) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
class EmployeeTokenObject(ApplicationToken):
|
||||
# Full hierarchy Employee[staff_id] -> Staff -> Duty -> Department -> Company
|
||||
|
||||
companies_id_list: List[int] # List of company objects
|
||||
companies_uu_id_list: List[str] # List of company objects
|
||||
|
||||
duty_id_list: List[int] # List of duty objects
|
||||
duty_uu_id_list: List[str] # List of duty objects
|
||||
|
||||
selected_company: Optional[CompanyToken] = None # Selected Company Object
|
||||
|
||||
@property
|
||||
def is_employee(self) -> bool:
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_occupant(self) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
TokenDictType = Union[EmployeeTokenObject, OccupantTokenObject]
|
||||
|
||||
|
||||
class TokenProvider:
|
||||
|
||||
AUTH_TOKEN: str = "AUTH_TOKEN"
|
||||
|
||||
@classmethod
|
||||
def convert_redis_object_to_token(
|
||||
cls, redis_object: Dict[str, Any]
|
||||
) -> TokenDictType:
|
||||
"""
|
||||
Process Redis object and return appropriate token object.
|
||||
"""
|
||||
if redis_object.get("user_type") == UserType.employee.value:
|
||||
return EmployeeTokenObject(**redis_object)
|
||||
elif redis_object.get("user_type") == UserType.occupant.value:
|
||||
return OccupantTokenObject(**redis_object)
|
||||
raise ValueError("Invalid user type")
|
||||
|
||||
@classmethod
|
||||
def get_dict_from_redis(
|
||||
cls, token: Optional[str] = None, user_uu_id: Optional[str] = None
|
||||
) -> Union[TokenDictType, List[TokenDictType]]:
|
||||
"""
|
||||
Retrieve token object from Redis using token and user_uu_id
|
||||
"""
|
||||
token_to_use, user_uu_id_to_use = token or "*", user_uu_id or "*"
|
||||
list_of_token_dict, auth_key_list = [], [
|
||||
cls.AUTH_TOKEN,
|
||||
token_to_use,
|
||||
user_uu_id_to_use,
|
||||
]
|
||||
if token:
|
||||
result = RedisActions.get_json(list_keys=auth_key_list, limit=1)
|
||||
if first_record := result.first:
|
||||
return cls.convert_redis_object_to_token(first_record)
|
||||
elif user_uu_id:
|
||||
result = RedisActions.get_json(list_keys=auth_key_list)
|
||||
if all_records := result.all:
|
||||
for all_record in all_records:
|
||||
list_of_token_dict.append(
|
||||
cls.convert_redis_object_to_token(all_record)
|
||||
)
|
||||
return list_of_token_dict
|
||||
raise ValueError(
|
||||
"Token not found in Redis. Please check the token or user_uu_id."
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def retrieve_application_codes(cls, page_url: str, token: TokenDictType):
|
||||
"""
|
||||
Retrieve application code from the token object or list of token objects.
|
||||
"""
|
||||
if isinstance(token, EmployeeTokenObject):
|
||||
if application_codes := token.selected_company.reachable_app_codes.get(
|
||||
page_url, None
|
||||
):
|
||||
return application_codes
|
||||
elif isinstance(token, OccupantTokenObject):
|
||||
if application_codes := token.selected_occupant.reachable_app_codes.get(
|
||||
page_url, None
|
||||
):
|
||||
return application_codes
|
||||
raise ValueError("Invalid token type or no application code found.")
|
||||
|
||||
@classmethod
|
||||
def retrieve_event_codes(cls, endpoint_code: str, token: TokenDictType) -> str:
|
||||
"""
|
||||
Retrieve event code from the token object or list of token objects.
|
||||
"""
|
||||
if isinstance(token, EmployeeTokenObject):
|
||||
if event_codes := token.selected_company.reachable_event_codes.get(
|
||||
endpoint_code, None
|
||||
):
|
||||
return event_codes
|
||||
elif isinstance(token, OccupantTokenObject):
|
||||
if event_codes := token.selected_occupant.reachable_event_codes.get(
|
||||
endpoint_code, None
|
||||
):
|
||||
return event_codes
|
||||
raise ValueError("Invalid token type or no event code found.")
|
||||
@@ -1,53 +0,0 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
"""
|
||||
"sex_code": "M",
|
||||
"country_code": "TR",
|
||||
"created_at": "2025-04-13 10:03:32 +00:00",
|
||||
"father_name": "Father",
|
||||
"birth_place": "Ankara",
|
||||
"updated_credentials_token": null,
|
||||
"cryp_uu_id": null,
|
||||
"mother_name": "Mother",
|
||||
"expiry_starts": "2025-04-13 10:03:32 +00:00",
|
||||
"confirmed_credentials_token": null,
|
||||
"surname": "Karatay",
|
||||
"firstname": "Berkay Super User",
|
||||
"birth_date": "1990-01-07 00:00:00 +00:00",
|
||||
"expiry_ends": "2099-12-31 00:00:00 +00:00",
|
||||
"is_confirmed": true,
|
||||
"is_email_send": false,
|
||||
"tax_no": "1231231232",
|
||||
"person_ref": "",
|
||||
"active": true,
|
||||
"deleted": false,
|
||||
"updated_at": "2025-04-13 10:03:32 +00:00",
|
||||
"uu_id": "b5b6e68f-a4d0-4d64-aa18-634671cb1299",
|
||||
"middle_name": "",
|
||||
"created_credentials_token": null,
|
||||
"person_tag": "BSU-System",
|
||||
"is_notification_send": false
|
||||
"""
|
||||
|
||||
|
||||
class REQUESTAWMXNTKMGPPOJWRCTZUBADNFLQDBDYVQAORFAVCSXUUHEBQHCEPCSKFBADBODFDBPYKOVINV(
|
||||
BaseModel
|
||||
):
|
||||
uu_id: str
|
||||
created_at: str
|
||||
updated_at: str
|
||||
person_tag: str
|
||||
expiry_starts: str
|
||||
expiry_ends: str
|
||||
firstname: str
|
||||
middle_name: str
|
||||
surname: str
|
||||
birth_date: str
|
||||
birth_place: str
|
||||
sex_code: str
|
||||
country_code: str
|
||||
tax_no: str
|
||||
active: bool
|
||||
deleted: bool
|
||||
is_confirmed: bool
|
||||
is_notification_send: bool
|
||||
Reference in New Issue
Block a user