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) == "" 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) == "" 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) == "" 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) == "" 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) == "" 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, )