from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: from core.essentials.observers.ConnectionObserver import ConnectionObserver from core.observers.TicketObserver import TicketObserver from core.Constants import Constants # from core.observers.BaseObserver import BaseObserver from core.models.manage.server_reply_tools import translate_server_failure, invalid_server_format from core.models.pydantic_models.type_checker import validate_model from core.models.pydantic_models.ServerReply import ServerReply from core.services.networking.httpx import connect # from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType from core.models.Result import Result, ResultError from core.errors.logger import logger def sync_ticket_prices( ticket_observer: TicketObserver, connection_observer: ConnectionObserver ) -> Result: notification = "Connecting to get Ticket Pricing..." ticket_observer.notify("connecting", subject=notification) rejected_list = [None, False, ""] base_url = Constants.TICKET_API_BASE_URL if base_url in rejected_list: notification = "Base URL is Empty, so it can't fetch prices.." ticket_observer.notify("failed_input", subject=notification) return {"valid": False, "error_code": "invalid_url"} url = f"{base_url}/sync" api_response = connect.single_endpoint( method="get", url=url, observer=connection_observer, payload=None ) #----------------------------- # EVALUATE CONNECTION FAILURE #----------------------------- # Layer 1: API failure: if not api_response.valid: error_msg = f"Connection/500s Error prevented the server from replying: {api_response.error_type} {api_response.message}" logger.error(error_msg) return Result(valid=False, error_type=ResultError.CONNECTION, message=error_msg) #----------------------------- # EVALUATE SERVER-SIDE ISSUES (assuming it replied) #----------------------------- # Layer 2: Validity of Server's Reply: raw_reply = api_response.data logger.info("Validating the Validity of the Server's Reply..") server_reply = validate_model(ServerReply, raw_reply) if not server_reply: logger.error(f"Invalid Structure for ServerReply! The raw data is {raw_reply}") return invalid_server_format() if not server_reply.valid: logger.error(f"Server reply was correctly structured, but the actual invoice failed to be created. The raw data is {raw_reply}") # translate by enum error code: return translate_server_failure(server_reply) #----------------------------- # EVALUATE SERVER'S ACTUAL DATA #----------------------------- # Layer 3: Payload Data payload_data = server_reply.data if not payload_data: logger.error(f"Failed to create an invoice object with this data: {payload_data}") return invalid_server_format() return Result(valid=True, data=payload_data) # return {"valid": True, "data": payload_data}