error raise now locates loc
This commit is contained in:
@@ -5,12 +5,17 @@ from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi import Request, HTTPException, status
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from api_objects.errors.errorMessages import EXCEPTION_DICTS, ERRORS_DICT, ERRORS_LANG
|
||||
from api_objects.errors.errorHandlers import (
|
||||
HTTPExceptionEvyos,
|
||||
HTTPExceptionAnyHandler,
|
||||
HTTPExceptionEvyosHandler,
|
||||
)
|
||||
|
||||
from middlewares.token_middleware import AuthHeaderMiddleware
|
||||
from application.create_file import create_app
|
||||
from api_objects.errors.errors_dictionary import ErrorHandlers
|
||||
from prometheus_fastapi_instrumentator import Instrumentator
|
||||
|
||||
|
||||
app = create_app(routers=routers)
|
||||
Instrumentator().instrument(app=app).expose(app=app)
|
||||
|
||||
@@ -25,17 +30,22 @@ app.add_middleware(
|
||||
)
|
||||
app.add_middleware(AuthHeaderMiddleware)
|
||||
|
||||
# Initialize error handlers
|
||||
error_handlers = ErrorHandlers.create(
|
||||
requests=Request,
|
||||
exceptions=HTTPException,
|
||||
response_model=JSONResponse,
|
||||
status=status,
|
||||
# Initialize Exception and ExceptionInstance handlers
|
||||
CustomExceptionHandler = HTTPExceptionEvyosHandler(
|
||||
**dict(
|
||||
statuses=status,
|
||||
exceptions=HTTPException,
|
||||
response_model=JSONResponse,
|
||||
exceptions_dict=EXCEPTION_DICTS,
|
||||
errors_dict=ERRORS_DICT,
|
||||
error_language_dict=ERRORS_LANG,
|
||||
)
|
||||
)
|
||||
CustomExceptionAnyHandler = HTTPExceptionAnyHandler(response_model=JSONResponse)
|
||||
|
||||
# Register error handlers with bound methods
|
||||
app.add_exception_handler(HTTPException, error_handlers.exception_handler_http)
|
||||
app.add_exception_handler(Exception, error_handlers.exception_handler_exception)
|
||||
app.add_exception_handler(HTTPExceptionEvyos, CustomExceptionHandler.handle_exception)
|
||||
app.add_exception_handler(Exception, CustomExceptionAnyHandler.any_exception_handler)
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn_config = {
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
__all__ = []
|
||||
from .validations_by_endpoint.router import validations_router
|
||||
|
||||
__all__ = ["validations_router"]
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
import json
|
||||
|
||||
from fastapi.routing import APIRouter
|
||||
from fastapi.requests import Request
|
||||
|
||||
from api_validations.validations_request import EndpointValidation
|
||||
from ApiServices.api_handlers.core_response import HTTPExceptionEvyos
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
validations_router = APIRouter(prefix="/validations", tags=["Validations"])
|
||||
validations_router.include_router(validations_router, include_in_schema=True)
|
||||
|
||||
|
||||
class EndpointValidationResponse(BaseModel):
|
||||
language: str
|
||||
headers: dict
|
||||
validation: dict
|
||||
|
||||
|
||||
class ValidationParser:
|
||||
|
||||
def __init__(self, active_validation):
|
||||
self.core_validation = active_validation
|
||||
self.annotations = (
|
||||
active_validation.model_json_schema() if active_validation else None
|
||||
)
|
||||
self.annotations = json.loads(json.dumps(self.annotations))
|
||||
self.schema = {}
|
||||
self.parse()
|
||||
|
||||
def parse(self):
|
||||
from api_validations.validations_request import PydanticBaseModel, CrudRecords
|
||||
properties = self.annotations.get("properties").items()
|
||||
for key, value in properties:
|
||||
default, title, type_field = value.get("default", None), value.get("title", ""), value.get("type", None)
|
||||
field_type, required, possible_types = "string", False, []
|
||||
if not type_field:
|
||||
for _ in value.get("anyOf") or []:
|
||||
type_opt = json.loads(json.dumps(_))
|
||||
if not type_opt.get("type") == "null":
|
||||
possible_types.append(type_opt.get("type"))
|
||||
field_type = possible_types[0]
|
||||
else:
|
||||
field_type, required = type_field, True
|
||||
total_class_annotations = {
|
||||
**self.core_validation.__annotations__
|
||||
**PydanticBaseModel.__annotations__,
|
||||
**CrudRecords.__annotations__,
|
||||
}
|
||||
attribute_of_class = total_class_annotations.get(key, None)
|
||||
if (
|
||||
str(attribute_of_class) == "<class 'str'>"
|
||||
or str(attribute_of_class) == "typing.Optional[str]"
|
||||
):
|
||||
field_type = "string"
|
||||
required = not str(attribute_of_class) == "typing.Optional[str]"
|
||||
elif (
|
||||
str(attribute_of_class) == "<class 'int'>"
|
||||
or str(attribute_of_class) == "typing.Optional[int]"
|
||||
):
|
||||
field_type = "integer"
|
||||
required = not str(attribute_of_class) == "typing.Optional[int]"
|
||||
elif (
|
||||
str(attribute_of_class) == "<class 'bool'>"
|
||||
or str(attribute_of_class) == "typing.Optional[bool]"
|
||||
):
|
||||
field_type = "boolean"
|
||||
required = not str(attribute_of_class) == "typing.Optional[bool]"
|
||||
elif (
|
||||
str(attribute_of_class) == "<class 'float'>"
|
||||
or str(attribute_of_class) == "typing.Optional[float]"
|
||||
):
|
||||
field_type = "float"
|
||||
required = not str(attribute_of_class) == "typing.Optional[bool]"
|
||||
elif (
|
||||
str(attribute_of_class) == "<class 'datetime.datetime'>"
|
||||
or str(attribute_of_class) == "typing.Optional[datetime.datetime]"
|
||||
):
|
||||
field_type = "datetime"
|
||||
required = (
|
||||
not str(attribute_of_class) == "typing.Optional[datetime.datetime]"
|
||||
)
|
||||
self.schema[key] = {"type": field_type, "required": required, "default": default}
|
||||
|
||||
@classmethod
|
||||
def retrieve_validation_from_class(cls, selected_event, events, lang):
|
||||
event_function_class = getattr(selected_event, "function_class", None)
|
||||
event_function_code = getattr(selected_event, "function_code", None)
|
||||
function_class = getattr(events, event_function_class, None)
|
||||
event_headers = function_class.retrieve_language_parameters(
|
||||
language=lang, function_code=event_function_code
|
||||
)
|
||||
event_validation = function_class.__event_validation__.get(
|
||||
event_function_code, [None]
|
||||
)[0]
|
||||
if not event_validation:
|
||||
raise HTTPExceptionEvyos(error_code="HTTP_400_BAD_REQUEST", lang=lang)
|
||||
return event_validation, event_headers
|
||||
|
||||
|
||||
@validations_router.post(path="/validations", summary="Get validations by endpoint")
|
||||
def validation_by_endpoint(request: Request, validation: EndpointValidation):
|
||||
import api_events.events as events
|
||||
|
||||
from api_services.redis.functions import RedisActions
|
||||
from databases import EndpointRestriction, Events
|
||||
|
||||
valid_token = RedisActions.get_object_via_access_key(request=request)
|
||||
language = str(valid_token.lang).lower()
|
||||
if not valid_token:
|
||||
raise HTTPExceptionEvyos(error_code="", lang=language)
|
||||
endpoint_active = EndpointRestriction.filter_one(
|
||||
EndpointRestriction.endpoint_name.ilike(f"%{str(validation.endpoint)}%"),
|
||||
system=True,
|
||||
).data
|
||||
if not endpoint_active:
|
||||
raise HTTPExceptionEvyos(error_code="HTTP_400_BAD_REQUEST", lang=language)
|
||||
if valid_token.user_type == 1 and not valid_token.selected_company:
|
||||
raise HTTPExceptionEvyos(error_code="HTTP_400_BAD_REQUEST", lang=language)
|
||||
elif valid_token.user_type == 2 and not valid_token.selected_occupant:
|
||||
raise HTTPExceptionEvyos(error_code="HTTP_400_BAD_REQUEST", lang=language)
|
||||
selected_event = Events.filter_one(
|
||||
Events.endpoint_id == endpoint_active.id,
|
||||
Events.id.in_(valid_token.selected_company.reachable_event_list_id),
|
||||
).data
|
||||
if not selected_event:
|
||||
raise HTTPExceptionEvyos(error_code="HTTP_400_BAD_REQUEST", lang=language)
|
||||
active_validation, active_headers = ValidationParser.retrieve_validation_from_class(
|
||||
selected_event=selected_event, events=events, lang=language
|
||||
)
|
||||
if not active_validation:
|
||||
raise HTTPExceptionEvyos(error_code="HTTP_400_BAD_REQUEST", lang=language)
|
||||
validation_parse = ValidationParser(active_validation=active_validation)
|
||||
return EndpointValidationResponse(
|
||||
language=language,
|
||||
headers=active_headers,
|
||||
validation=validation_parse.schema,
|
||||
)
|
||||
Reference in New Issue
Block a user