diff --git a/AlpineBits-HotelData-2024-10/AlpineBits-HotelData-2024-10.pdf b/AlpineBits-HotelData-2024-10/AlpineBits-HotelData-2024-10.pdf index 0ea9a94..ac56209 100644 Binary files a/AlpineBits-HotelData-2024-10/AlpineBits-HotelData-2024-10.pdf and b/AlpineBits-HotelData-2024-10/AlpineBits-HotelData-2024-10.pdf differ diff --git a/pyproject.toml b/pyproject.toml index 2704ffb..e8dfcdd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,7 @@ requires-python = ">=3.13" dependencies = [ "generateds>=2.44.3", "lxml>=6.0.1", + "ruff>=0.13.1", "xsdata-pydantic[cli,lxml,soap]>=24.5", "xsdata[cli,lxml,soap]>=25.7", ] diff --git a/src/alpinebits_guestrequests.py b/src/alpinebits_guestrequests.py index e6f8629..c2f797a 100644 --- a/src/alpinebits_guestrequests.py +++ b/src/alpinebits_guestrequests.py @@ -3,12 +3,16 @@ from datetime import datetime, timezone from typing import List, Optional - - - # TimeSpan class according to XSD: class TimeSpan: - def __init__(self, start: str, end: str = None, duration: str = None, start_window: str = None, end_window: str = None): + def __init__( + self, + start: str, + end: str = None, + duration: str = None, + start_window: str = None, + end_window: str = None, + ): self.start = start self.end = end self.duration = duration @@ -29,16 +33,27 @@ class TimeSpan: NAMESPACE = "http://www.opentravel.org/OTA/2003/05" -ET.register_namespace('', NAMESPACE) +ET.register_namespace("", NAMESPACE) def _ns(tag): return f"{{{NAMESPACE}}}{tag}" - class ResGuest: - def __init__(self, given_name: str, surname: str, gender: Optional[str] = None, birth_date: Optional[str] = None, language: Optional[str] = None, name_prefix: Optional[str] = None, name_title: Optional[str] = None, email: Optional[str] = None, address: Optional[dict] = None, telephones: Optional[list] = None): + def __init__( + self, + given_name: str, + surname: str, + gender: Optional[str] = None, + birth_date: Optional[str] = None, + language: Optional[str] = None, + name_prefix: Optional[str] = None, + name_title: Optional[str] = None, + email: Optional[str] = None, + address: Optional[dict] = None, + telephones: Optional[list] = None, + ): self.given_name = given_name self.surname = surname self.gender = gender @@ -91,6 +106,7 @@ class ResGuest: def __str__(self): from lxml import etree + elem = self.to_xml() xml_bytes = ET.tostring(elem, encoding="utf-8") parser = etree.XMLParser(remove_blank_text=True) @@ -98,14 +114,6 @@ class ResGuest: return etree.tostring(lxml_elem, pretty_print=True, encoding="unicode") - - - - - - - - class RoomStay: def __init__(self, room_type: str, timespan: TimeSpan, guests: List[ResGuest]): self.room_type = room_type @@ -114,7 +122,9 @@ class RoomStay: def to_xml(self): roomstay_elem = ET.Element(_ns("RoomStay")) - ET.SubElement(roomstay_elem, _ns("RoomType")).set("RoomTypeCode", self.room_type) + ET.SubElement(roomstay_elem, _ns("RoomType")).set( + "RoomTypeCode", self.room_type + ) roomstay_elem.append(self.timespan.to_xml()) guests_elem = ET.SubElement(roomstay_elem, _ns("Guests")) for guest in self.guests: @@ -123,6 +133,7 @@ class RoomStay: def __str__(self): from lxml import etree + elem = self.to_xml() xml_bytes = ET.tostring(elem, encoding="utf-8") parser = etree.XMLParser(remove_blank_text=True) @@ -131,7 +142,13 @@ class RoomStay: class Reservation: - def __init__(self, reservation_id: str, hotel_code: str, roomstays: List[RoomStay], create_time: Optional[str] = None): + def __init__( + self, + reservation_id: str, + hotel_code: str, + roomstays: List[RoomStay], + create_time: Optional[str] = None, + ): self.reservation_id = reservation_id self.hotel_code = hotel_code self.roomstays = roomstays @@ -151,10 +168,10 @@ class Reservation: return res_elem def to_xml_string(self): - root = ET.Element(_ns("OTA_ResRetrieveRS"), { - "Version": "2024-10", - "TimeStamp": datetime.now(timezone.utc).isoformat() - }) + root = ET.Element( + _ns("OTA_ResRetrieveRS"), + {"Version": "2024-10", "TimeStamp": datetime.now(timezone.utc).isoformat()}, + ) success_elem = ET.SubElement(root, _ns("Success")) reservations_list = ET.SubElement(root, _ns("ReservationsList")) reservations_list.append(self.to_xml()) diff --git a/src/generated/alpinebits.py b/src/generated/alpinebits.py index 004bbf9..42c9ff3 100644 --- a/src/generated/alpinebits.py +++ b/src/generated/alpinebits.py @@ -238,9 +238,7 @@ class OtaHotelRatePlanRq(BaseModel): class RatePlan(BaseModel): model_config = ConfigDict(defer_build=True) - date_range: list[ - "OtaHotelRatePlanRq.RatePlans.RatePlan.DateRange" - ] = field( + date_range: list["OtaHotelRatePlanRq.RatePlans.RatePlan.DateRange"] = field( default_factory=list, metadata={ "name": "DateRange", @@ -256,9 +254,7 @@ class OtaHotelRatePlanRq(BaseModel): "type": "Element", }, ) - hotel_ref: list[ - "OtaHotelRatePlanRq.RatePlans.RatePlan.HotelRef" - ] = field( + hotel_ref: list["OtaHotelRatePlanRq.RatePlans.RatePlan.HotelRef"] = field( default_factory=list, metadata={ "name": "HotelRef", @@ -907,9 +903,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "type": "Element", }, ) - info_code: Optional[ - MultimediaDescriptionInfoCode1 - ] = field( + info_code: Optional[MultimediaDescriptionInfoCode1] = field( default=None, metadata={ "name": "InfoCode", @@ -961,9 +955,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -971,14 +963,12 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "min_length": 1, }, ) - text_format: DescriptionTextFormat1 = ( - field( - metadata={ - "name": "TextFormat", - "type": "Attribute", - "required": True, - } - ) + text_format: DescriptionTextFormat1 = field( + metadata={ + "name": "TextFormat", + "type": "Attribute", + "required": True, + } ) language: str = field( metadata={ @@ -1029,9 +1019,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class ImageFormat(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) url: str = field( metadata={ "name": "URL", @@ -1040,16 +1028,14 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "pattern": r"https?://.+", } ) - copyright_notice: Optional[str] = ( - field( - default=None, - metadata={ - "name": "CopyrightNotice", - "type": "Attribute", - "min_length": 1, - "max_length": 64, - }, - ) + copyright_notice: Optional[str] = field( + default=None, + metadata={ + "name": "CopyrightNotice", + "type": "Attribute", + "min_length": 1, + "max_length": 64, + }, ) source_id: Optional[str] = field( default=None, @@ -1069,15 +1055,13 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "max_length": 64, }, ) - applicable_start: Optional[str] = ( - field( - default=None, - metadata={ - "name": "ApplicableStart", - "type": "Attribute", - "pattern": r"--[0-1][0-9]-[0-3][0-9]", - }, - ) + applicable_start: Optional[str] = field( + default=None, + metadata={ + "name": "ApplicableStart", + "type": "Attribute", + "pattern": r"--[0-1][0-9]-[0-3][0-9]", + }, ) applicable_end: Optional[str] = field( default=None, @@ -1089,9 +1073,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -1099,14 +1081,12 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "min_length": 1, }, ) - text_format: DescriptionTextFormat1 = ( - field( - metadata={ - "name": "TextFormat", - "type": "Attribute", - "required": True, - } - ) + text_format: DescriptionTextFormat1 = field( + metadata={ + "name": "TextFormat", + "type": "Attribute", + "required": True, + } ) language: str = field( metadata={ @@ -1157,9 +1137,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class VideoFormat(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) url: str = field( metadata={ "name": "URL", @@ -1168,16 +1146,14 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "pattern": r"https?://.+", } ) - copyright_notice: Optional[str] = ( - field( - default=None, - metadata={ - "name": "CopyrightNotice", - "type": "Attribute", - "min_length": 1, - "max_length": 64, - }, - ) + copyright_notice: Optional[str] = field( + default=None, + metadata={ + "name": "CopyrightNotice", + "type": "Attribute", + "min_length": 1, + "max_length": 64, + }, ) source_id: Optional[str] = field( default=None, @@ -1197,21 +1173,17 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "max_length": 64, }, ) - applicable_start: Optional[str] = ( - field( - default=None, - metadata={ - "name": "ApplicableStart", - "type": "Attribute", - "pattern": r"[0-1][0-9]-[0-3][0-9]", - }, - ) + applicable_start: Optional[str] = field( + default=None, + metadata={ + "name": "ApplicableStart", + "type": "Attribute", + "pattern": r"[0-1][0-9]-[0-3][0-9]", + }, ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -1219,14 +1191,12 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "min_length": 1, }, ) - text_format: DescriptionTextFormat1 = ( - field( - metadata={ - "name": "TextFormat", - "type": "Attribute", - "required": True, - } - ) + text_format: DescriptionTextFormat1 = field( + metadata={ + "name": "TextFormat", + "type": "Attribute", + "required": True, + } ) language: str = field( metadata={ @@ -1539,14 +1509,14 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "type": "Element", }, ) - info_code: Optional[ - MultimediaDescriptionInfoCode2 - ] = field( - default=None, - metadata={ - "name": "InfoCode", - "type": "Attribute", - }, + info_code: Optional[MultimediaDescriptionInfoCode2] = ( + field( + default=None, + metadata={ + "name": "InfoCode", + "type": "Attribute", + }, + ) ) class TextItems(BaseModel): @@ -1560,9 +1530,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class TextItem(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) description: list[ "OtaHotelDescriptiveContentNotifRq.HotelDescriptiveContents.HotelDescriptiveContent.FacilityInfo.GuestRooms.GuestRoom.MultimediaDescriptions.MultimediaDescription.TextItems.TextItem.Description" ] = field( @@ -1575,9 +1543,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -1615,9 +1581,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class ImageItem(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) image_format: "OtaHotelDescriptiveContentNotifRq.HotelDescriptiveContents.HotelDescriptiveContent.FacilityInfo.GuestRooms.GuestRoom.MultimediaDescriptions.MultimediaDescription.ImageItems.ImageItem.ImageFormat" = field( metadata={ "name": "ImageFormat", @@ -1644,9 +1608,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class ImageFormat(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) url: str = field( metadata={ "name": "URL", @@ -1655,22 +1617,18 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "pattern": r"https?://.+", } ) - copyright_notice: Optional[str] = ( - field( - default=None, - metadata={ - "name": "CopyrightNotice", - "type": "Attribute", - "min_length": 1, - "max_length": 64, - }, - ) + copyright_notice: Optional[str] = field( + default=None, + metadata={ + "name": "CopyrightNotice", + "type": "Attribute", + "min_length": 1, + "max_length": 64, + }, ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -2067,14 +2025,14 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): "type": "Attribute", }, ) - charge_frequency: Optional[ - TaxPolicyChargeFrequency - ] = field( - default=None, - metadata={ - "name": "ChargeFrequency", - "type": "Attribute", - }, + charge_frequency: Optional[TaxPolicyChargeFrequency] = ( + field( + default=None, + metadata={ + "name": "ChargeFrequency", + "type": "Attribute", + }, + ) ) charge_unit: Optional[TaxPolicyChargeUnit] = field( default=None, @@ -2204,9 +2162,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class BankAcct(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) bank_acct_name: str = field( metadata={ "name": "BankAcctName", @@ -2232,9 +2188,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class BankAcctNumber(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) plain_text: str = field( metadata={ "name": "PlainText", @@ -2245,9 +2199,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class BankId(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) plain_text: str = field( metadata={ "name": "PlainText", @@ -2258,9 +2210,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class Cash(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) cash_indicator: str = field( metadata={ "name": "CashIndicator", @@ -2271,9 +2221,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): ) class PaymentCard(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) card_type: Optional[str] = field( default=None, metadata={ @@ -2356,9 +2304,7 @@ class OtaHotelDescriptiveContentNotifRq(BaseModel): class StayRequirement(BaseModel): model_config = ConfigDict(defer_build=True) - stay_context: Optional[ - StayRequirementStayContext - ] = field( + stay_context: Optional[StayRequirementStayContext] = field( default=None, metadata={ "name": "StayContext", @@ -2778,15 +2724,13 @@ class OtaHotelDescriptiveContentNotifRs(BaseModel): class Warnings(BaseModel): model_config = ConfigDict(defer_build=True) - warning: list["OtaHotelDescriptiveContentNotifRs.Warnings.Warning"] = ( - field( - default_factory=list, - metadata={ - "name": "Warning", - "type": "Element", - "min_occurs": 1, - }, - ) + warning: list["OtaHotelDescriptiveContentNotifRs.Warnings.Warning"] = field( + default_factory=list, + metadata={ + "name": "Warning", + "type": "Element", + "min_occurs": 1, + }, ) class Warning(BaseModel): @@ -3188,9 +3132,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "type": "Element", }, ) - info_code: Optional[ - MultimediaDescriptionInfoCode1 - ] = field( + info_code: Optional[MultimediaDescriptionInfoCode1] = field( default=None, metadata={ "name": "InfoCode", @@ -3242,9 +3184,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -3252,14 +3192,12 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "min_length": 1, }, ) - text_format: DescriptionTextFormat1 = ( - field( - metadata={ - "name": "TextFormat", - "type": "Attribute", - "required": True, - } - ) + text_format: DescriptionTextFormat1 = field( + metadata={ + "name": "TextFormat", + "type": "Attribute", + "required": True, + } ) language: str = field( metadata={ @@ -3310,9 +3248,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class ImageFormat(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) url: str = field( metadata={ "name": "URL", @@ -3321,16 +3257,14 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "pattern": r"https?://.+", } ) - copyright_notice: Optional[str] = ( - field( - default=None, - metadata={ - "name": "CopyrightNotice", - "type": "Attribute", - "min_length": 1, - "max_length": 64, - }, - ) + copyright_notice: Optional[str] = field( + default=None, + metadata={ + "name": "CopyrightNotice", + "type": "Attribute", + "min_length": 1, + "max_length": 64, + }, ) source_id: Optional[str] = field( default=None, @@ -3350,15 +3284,13 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "max_length": 64, }, ) - applicable_start: Optional[str] = ( - field( - default=None, - metadata={ - "name": "ApplicableStart", - "type": "Attribute", - "pattern": r"--[0-1][0-9]-[0-3][0-9]", - }, - ) + applicable_start: Optional[str] = field( + default=None, + metadata={ + "name": "ApplicableStart", + "type": "Attribute", + "pattern": r"--[0-1][0-9]-[0-3][0-9]", + }, ) applicable_end: Optional[str] = field( default=None, @@ -3370,9 +3302,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -3380,14 +3310,12 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "min_length": 1, }, ) - text_format: DescriptionTextFormat1 = ( - field( - metadata={ - "name": "TextFormat", - "type": "Attribute", - "required": True, - } - ) + text_format: DescriptionTextFormat1 = field( + metadata={ + "name": "TextFormat", + "type": "Attribute", + "required": True, + } ) language: str = field( metadata={ @@ -3438,9 +3366,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class VideoFormat(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) url: str = field( metadata={ "name": "URL", @@ -3449,16 +3375,14 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "pattern": r"https?://.+", } ) - copyright_notice: Optional[str] = ( - field( - default=None, - metadata={ - "name": "CopyrightNotice", - "type": "Attribute", - "min_length": 1, - "max_length": 64, - }, - ) + copyright_notice: Optional[str] = field( + default=None, + metadata={ + "name": "CopyrightNotice", + "type": "Attribute", + "min_length": 1, + "max_length": 64, + }, ) source_id: Optional[str] = field( default=None, @@ -3478,21 +3402,17 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "max_length": 64, }, ) - applicable_start: Optional[str] = ( - field( - default=None, - metadata={ - "name": "ApplicableStart", - "type": "Attribute", - "pattern": r"[0-1][0-9]-[0-3][0-9]", - }, - ) + applicable_start: Optional[str] = field( + default=None, + metadata={ + "name": "ApplicableStart", + "type": "Attribute", + "pattern": r"[0-1][0-9]-[0-3][0-9]", + }, ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -3500,14 +3420,12 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "min_length": 1, }, ) - text_format: DescriptionTextFormat1 = ( - field( - metadata={ - "name": "TextFormat", - "type": "Attribute", - "required": True, - } - ) + text_format: DescriptionTextFormat1 = field( + metadata={ + "name": "TextFormat", + "type": "Attribute", + "required": True, + } ) language: str = field( metadata={ @@ -3820,14 +3738,14 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "type": "Element", }, ) - info_code: Optional[ - MultimediaDescriptionInfoCode2 - ] = field( - default=None, - metadata={ - "name": "InfoCode", - "type": "Attribute", - }, + info_code: Optional[MultimediaDescriptionInfoCode2] = ( + field( + default=None, + metadata={ + "name": "InfoCode", + "type": "Attribute", + }, + ) ) class TextItems(BaseModel): @@ -3841,9 +3759,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class TextItem(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) description: list[ "OtaHotelDescriptiveInfoRs.HotelDescriptiveContents.HotelDescriptiveContent.FacilityInfo.GuestRooms.GuestRoom.MultimediaDescriptions.MultimediaDescription.TextItems.TextItem.Description" ] = field( @@ -3856,9 +3772,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -3896,9 +3810,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class ImageItem(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) image_format: "OtaHotelDescriptiveInfoRs.HotelDescriptiveContents.HotelDescriptiveContent.FacilityInfo.GuestRooms.GuestRoom.MultimediaDescriptions.MultimediaDescription.ImageItems.ImageItem.ImageFormat" = field( metadata={ "name": "ImageFormat", @@ -3925,9 +3837,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class ImageFormat(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) url: str = field( metadata={ "name": "URL", @@ -3936,22 +3846,18 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "pattern": r"https?://.+", } ) - copyright_notice: Optional[str] = ( - field( - default=None, - metadata={ - "name": "CopyrightNotice", - "type": "Attribute", - "min_length": 1, - "max_length": 64, - }, - ) + copyright_notice: Optional[str] = field( + default=None, + metadata={ + "name": "CopyrightNotice", + "type": "Attribute", + "min_length": 1, + "max_length": 64, + }, ) class Description(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -4348,14 +4254,14 @@ class OtaHotelDescriptiveInfoRs(BaseModel): "type": "Attribute", }, ) - charge_frequency: Optional[ - TaxPolicyChargeFrequency - ] = field( - default=None, - metadata={ - "name": "ChargeFrequency", - "type": "Attribute", - }, + charge_frequency: Optional[TaxPolicyChargeFrequency] = ( + field( + default=None, + metadata={ + "name": "ChargeFrequency", + "type": "Attribute", + }, + ) ) charge_unit: Optional[TaxPolicyChargeUnit] = field( default=None, @@ -4485,9 +4391,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class BankAcct(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) bank_acct_name: str = field( metadata={ "name": "BankAcctName", @@ -4513,9 +4417,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class BankAcctNumber(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) plain_text: str = field( metadata={ "name": "PlainText", @@ -4526,9 +4428,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class BankId(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) plain_text: str = field( metadata={ "name": "PlainText", @@ -4539,9 +4439,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class Cash(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) cash_indicator: str = field( metadata={ "name": "CashIndicator", @@ -4552,9 +4450,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): ) class PaymentCard(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) card_type: Optional[str] = field( default=None, metadata={ @@ -4637,9 +4533,7 @@ class OtaHotelDescriptiveInfoRs(BaseModel): class StayRequirement(BaseModel): model_config = ConfigDict(defer_build=True) - stay_context: Optional[ - StayRequirementStayContext - ] = field( + stay_context: Optional[StayRequirementStayContext] = field( default=None, metadata={ "name": "StayContext", @@ -5025,15 +4919,13 @@ class OtaHotelInvCountNotifRq(BaseModel): class Inventories(BaseModel): model_config = ConfigDict(defer_build=True) - inventory: list["OtaHotelInvCountNotifRq.Inventories.Inventory"] = ( - field( - default_factory=list, - metadata={ - "name": "Inventory", - "type": "Element", - "min_occurs": 1, - }, - ) + inventory: list["OtaHotelInvCountNotifRq.Inventories.Inventory"] = field( + default_factory=list, + metadata={ + "name": "Inventory", + "type": "Element", + "min_occurs": 1, + }, ) hotel_code: str = field( metadata={ @@ -5309,9 +5201,7 @@ class OtaHotelPostEventNotifRq(BaseModel): class EventReports(BaseModel): model_config = ConfigDict(defer_build=True) - event_report: list[ - "OtaHotelPostEventNotifRq.EventReports.EventReport" - ] = field( + event_report: list["OtaHotelPostEventNotifRq.EventReports.EventReport"] = field( default_factory=list, metadata={ "name": "EventReport", @@ -5630,14 +5520,12 @@ class OtaHotelPostEventNotifRq(BaseModel): "required": True, } ) - end: Optional[Union[XmlDate, XmlDateTime, XmlTime]] = ( - field( - default=None, - metadata={ - "name": "End", - "type": "Attribute", - }, - ) + end: Optional[Union[XmlDate, XmlDateTime, XmlTime]] = field( + default=None, + metadata={ + "name": "End", + "type": "Attribute", + }, ) class EndDateWindow(BaseModel): @@ -5992,9 +5880,7 @@ class OtaHotelRatePlanNotifRq(BaseModel): "type": "Element", }, ) - rates: Optional[ - "OtaHotelRatePlanNotifRq.RatePlans.RatePlan.Rates" - ] = field( + rates: Optional["OtaHotelRatePlanNotifRq.RatePlans.RatePlan.Rates"] = field( default=None, metadata={ "name": "Rates", @@ -6010,14 +5896,14 @@ class OtaHotelRatePlanNotifRq(BaseModel): "type": "Element", }, ) - offers: Optional[ - "OtaHotelRatePlanNotifRq.RatePlans.RatePlan.Offers" - ] = field( - default=None, - metadata={ - "name": "Offers", - "type": "Element", - }, + offers: Optional["OtaHotelRatePlanNotifRq.RatePlans.RatePlan.Offers"] = ( + field( + default=None, + metadata={ + "name": "Offers", + "type": "Element", + }, + ) ) description: list[ "OtaHotelRatePlanNotifRq.RatePlans.RatePlan.Description" @@ -6210,12 +6096,14 @@ class OtaHotelRatePlanNotifRq(BaseModel): "required": True, } ) - min_max_message_type: LengthOfStayMinMaxMessageType1 = field( - metadata={ - "name": "MinMaxMessageType", - "type": "Attribute", - "required": True, - } + min_max_message_type: LengthOfStayMinMaxMessageType1 = ( + field( + metadata={ + "name": "MinMaxMessageType", + "type": "Attribute", + "required": True, + } + ) ) class DowRestrictions(BaseModel): @@ -6359,14 +6247,12 @@ class OtaHotelRatePlanNotifRq(BaseModel): class RestrictionStatus(BaseModel): model_config = ConfigDict(defer_build=True) - restriction: Optional[RestrictionStatusRestriction] = ( - field( - default=None, - metadata={ - "name": "Restriction", - "type": "Attribute", - }, - ) + restriction: Optional[RestrictionStatusRestriction] = field( + default=None, + metadata={ + "name": "Restriction", + "type": "Attribute", + }, ) status: Optional[RestrictionStatusStatus] = field( default=None, @@ -6378,15 +6264,15 @@ class OtaHotelRatePlanNotifRq(BaseModel): class Rates(BaseModel): model_config = ConfigDict(defer_build=True) - rate: list[ - "OtaHotelRatePlanNotifRq.RatePlans.RatePlan.Rates.Rate" - ] = field( - default_factory=list, - metadata={ - "name": "Rate", - "type": "Element", - "min_occurs": 1, - }, + rate: list["OtaHotelRatePlanNotifRq.RatePlans.RatePlan.Rates.Rate"] = ( + field( + default_factory=list, + metadata={ + "name": "Rate", + "type": "Element", + "min_occurs": 1, + }, + ) ) class Rate(BaseModel): @@ -6718,9 +6604,7 @@ class OtaHotelRatePlanNotifRq(BaseModel): "pattern": r"\S+", }, ) - meal_plan_codes: Optional[ - MealsIncludedMealPlanCodes - ] = field( + meal_plan_codes: Optional[MealsIncludedMealPlanCodes] = field( default=None, metadata={ "name": "MealPlanCodes", @@ -6780,14 +6664,12 @@ class OtaHotelRatePlanNotifRq(BaseModel): "type": "Attribute", }, ) - charge_type_code: Optional[SupplementChargeTypeCode] = ( - field( - default=None, - metadata={ - "name": "ChargeTypeCode", - "type": "Attribute", - }, - ) + charge_type_code: Optional[SupplementChargeTypeCode] = field( + default=None, + metadata={ + "name": "ChargeTypeCode", + "type": "Attribute", + }, ) amount: Optional[str] = field( default=None, @@ -7319,12 +7201,14 @@ class OtaHotelRatePlanNotifRq(BaseModel): "pattern": r"[0-9]+", } ) - first_qualifying_position: GuestFirstQualifyingPosition = field( - metadata={ - "name": "FirstQualifyingPosition", - "type": "Attribute", - "required": True, - } + first_qualifying_position: GuestFirstQualifyingPosition = ( + field( + metadata={ + "name": "FirstQualifyingPosition", + "type": "Attribute", + "required": True, + } + ) ) last_qualifying_position: str = field( metadata={ @@ -7716,14 +7600,12 @@ class OtaHotelRatePlanRs(BaseModel): "type": "Element", }, ) - rates: Optional["OtaHotelRatePlanRs.RatePlans.RatePlan.Rates"] = ( - field( - default=None, - metadata={ - "name": "Rates", - "type": "Element", - }, - ) + rates: Optional["OtaHotelRatePlanRs.RatePlans.RatePlan.Rates"] = field( + default=None, + metadata={ + "name": "Rates", + "type": "Element", + }, ) supplements: Optional[ "OtaHotelRatePlanRs.RatePlans.RatePlan.Supplements" @@ -7734,24 +7616,22 @@ class OtaHotelRatePlanRs(BaseModel): "type": "Element", }, ) - offers: Optional[ - "OtaHotelRatePlanRs.RatePlans.RatePlan.Offers" - ] = field( + offers: Optional["OtaHotelRatePlanRs.RatePlans.RatePlan.Offers"] = field( default=None, metadata={ "name": "Offers", "type": "Element", }, ) - description: list[ - "OtaHotelRatePlanRs.RatePlans.RatePlan.Description" - ] = field( - default_factory=list, - metadata={ - "name": "Description", - "type": "Element", - "max_occurs": 5, - }, + description: list["OtaHotelRatePlanRs.RatePlans.RatePlan.Description"] = ( + field( + default_factory=list, + metadata={ + "name": "Description", + "type": "Element", + "max_occurs": 5, + }, + ) ) start: Optional[str] = field( default=None, @@ -7934,12 +7814,14 @@ class OtaHotelRatePlanRs(BaseModel): "required": True, } ) - min_max_message_type: LengthOfStayMinMaxMessageType1 = field( - metadata={ - "name": "MinMaxMessageType", - "type": "Attribute", - "required": True, - } + min_max_message_type: LengthOfStayMinMaxMessageType1 = ( + field( + metadata={ + "name": "MinMaxMessageType", + "type": "Attribute", + "required": True, + } + ) ) class DowRestrictions(BaseModel): @@ -8083,14 +7965,12 @@ class OtaHotelRatePlanRs(BaseModel): class RestrictionStatus(BaseModel): model_config = ConfigDict(defer_build=True) - restriction: Optional[RestrictionStatusRestriction] = ( - field( - default=None, - metadata={ - "name": "Restriction", - "type": "Attribute", - }, - ) + restriction: Optional[RestrictionStatusRestriction] = field( + default=None, + metadata={ + "name": "Restriction", + "type": "Attribute", + }, ) status: Optional[RestrictionStatusStatus] = field( default=None, @@ -8102,9 +7982,7 @@ class OtaHotelRatePlanRs(BaseModel): class Rates(BaseModel): model_config = ConfigDict(defer_build=True) - rate: list[ - "OtaHotelRatePlanRs.RatePlans.RatePlan.Rates.Rate" - ] = field( + rate: list["OtaHotelRatePlanRs.RatePlans.RatePlan.Rates.Rate"] = field( default_factory=list, metadata={ "name": "Rate", @@ -8442,9 +8320,7 @@ class OtaHotelRatePlanRs(BaseModel): "pattern": r"\S+", }, ) - meal_plan_codes: Optional[ - MealsIncludedMealPlanCodes - ] = field( + meal_plan_codes: Optional[MealsIncludedMealPlanCodes] = field( default=None, metadata={ "name": "MealPlanCodes", @@ -8504,14 +8380,12 @@ class OtaHotelRatePlanRs(BaseModel): "type": "Attribute", }, ) - charge_type_code: Optional[SupplementChargeTypeCode] = ( - field( - default=None, - metadata={ - "name": "ChargeTypeCode", - "type": "Attribute", - }, - ) + charge_type_code: Optional[SupplementChargeTypeCode] = field( + default=None, + metadata={ + "name": "ChargeTypeCode", + "type": "Attribute", + }, ) amount: Optional[str] = field( default=None, @@ -8652,16 +8526,16 @@ class OtaHotelRatePlanRs(BaseModel): class Offers(BaseModel): model_config = ConfigDict(defer_build=True) - offer: list[ - "OtaHotelRatePlanRs.RatePlans.RatePlan.Offers.Offer" - ] = field( - default_factory=list, - metadata={ - "name": "Offer", - "type": "Element", - "min_occurs": 1, - "max_occurs": 3, - }, + offer: list["OtaHotelRatePlanRs.RatePlans.RatePlan.Offers.Offer"] = ( + field( + default_factory=list, + metadata={ + "name": "Offer", + "type": "Element", + "min_occurs": 1, + "max_occurs": 3, + }, + ) ) class Offer(BaseModel): @@ -9043,12 +8917,14 @@ class OtaHotelRatePlanRs(BaseModel): "pattern": r"[0-9]+", } ) - first_qualifying_position: GuestFirstQualifyingPosition = field( - metadata={ - "name": "FirstQualifyingPosition", - "type": "Attribute", - "required": True, - } + first_qualifying_position: GuestFirstQualifyingPosition = ( + field( + metadata={ + "name": "FirstQualifyingPosition", + "type": "Attribute", + "required": True, + } + ) ) last_qualifying_position: str = field( metadata={ @@ -9077,14 +8953,14 @@ class OtaHotelRatePlanRs(BaseModel): "pattern": r"https?://.+", }, ) - text: list[ - "OtaHotelRatePlanRs.RatePlans.RatePlan.Description.Text" - ] = field( - default_factory=list, - metadata={ - "name": "Text", - "type": "Element", - }, + text: list["OtaHotelRatePlanRs.RatePlans.RatePlan.Description.Text"] = ( + field( + default_factory=list, + metadata={ + "name": "Text", + "type": "Element", + }, + ) ) url: list[str] = field( default_factory=list, @@ -9479,22 +9355,22 @@ class OtaHotelResNotifRq(BaseModel): class MealsIncluded(BaseModel): model_config = ConfigDict(defer_build=True) - meal_plan_indicator: MealsIncludedMealPlanIndicator = field( - metadata={ - "name": "MealPlanIndicator", - "type": "Attribute", - "required": True, - } - ) - meal_plan_codes: MealsIncludedMealPlanCodes = ( + meal_plan_indicator: MealsIncludedMealPlanIndicator = ( field( metadata={ - "name": "MealPlanCodes", + "name": "MealPlanIndicator", "type": "Attribute", "required": True, } ) ) + meal_plan_codes: MealsIncludedMealPlanCodes = field( + metadata={ + "name": "MealPlanCodes", + "type": "Attribute", + "required": True, + } + ) class RoomRates(BaseModel): model_config = ConfigDict(defer_build=True) @@ -9575,9 +9451,7 @@ class OtaHotelResNotifRq(BaseModel): "pattern": r"\S+", }, ) - expire_date_exclusive_ind: Optional[ - str - ] = field( + expire_date_exclusive_ind: Optional[str] = field( default=None, metadata={ "name": "ExpireDateExclusiveInd", @@ -9585,9 +9459,7 @@ class OtaHotelResNotifRq(BaseModel): "pattern": r"\S+", }, ) - rate_time_unit: Optional[ - RateRateTimeUnit - ] = field( + rate_time_unit: Optional[RateRateTimeUnit] = field( default=None, metadata={ "name": "RateTimeUnit", @@ -9604,19 +9476,15 @@ class OtaHotelResNotifRq(BaseModel): ) class Base(BaseModel): - model_config = ConfigDict( - defer_build=True - ) - amount_after_tax: Optional[str] = ( - field( - default=None, - metadata={ - "name": "AmountAfterTax", - "type": "Attribute", - "min_exclusive": "0.0", - "pattern": r"[0-9]*\.?[0-9]*", - }, - ) + model_config = ConfigDict(defer_build=True) + amount_after_tax: Optional[str] = field( + default=None, + metadata={ + "name": "AmountAfterTax", + "type": "Attribute", + "min_exclusive": "0.0", + "pattern": r"[0-9]*\.?[0-9]*", + }, ) currency_code: Optional[str] = field( default=None, @@ -9781,9 +9649,7 @@ class OtaHotelResNotifRq(BaseModel): ) class CardNumber(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) plain_text: Optional[str] = field( default=None, metadata={ @@ -9800,15 +9666,13 @@ class OtaHotelResNotifRq(BaseModel): "min_length": 1, }, ) - encryption_method: Optional[str] = ( - field( - default=None, - metadata={ - "name": "EncryptionMethod", - "type": "Attribute", - "min_length": 1, - }, - ) + encryption_method: Optional[str] = field( + default=None, + metadata={ + "name": "EncryptionMethod", + "type": "Attribute", + "min_length": 1, + }, ) class Total(BaseModel): @@ -10236,9 +10100,7 @@ class OtaHotelResNotifRq(BaseModel): ) class PersonName(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) name_prefix: Optional[str] = field( default=None, metadata={ @@ -10277,9 +10139,7 @@ class OtaHotelResNotifRq(BaseModel): ) class Telephone(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) phone_tech_type: Optional[str] = field( default=None, metadata={ @@ -10298,9 +10158,7 @@ class OtaHotelResNotifRq(BaseModel): ) class Email(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -10318,9 +10176,7 @@ class OtaHotelResNotifRq(BaseModel): ) class Address(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) address_line: Optional[str] = field( default=None, metadata={ @@ -10367,9 +10223,7 @@ class OtaHotelResNotifRq(BaseModel): ) class CountryName(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) code: str = field( metadata={ "name": "Code", @@ -10666,9 +10520,7 @@ class OtaHotelResNotifRq(BaseModel): "type": "Attribute", }, ) - payment_transaction_type_code: Optional[ - object - ] = field( + payment_transaction_type_code: Optional[object] = field( default=None, metadata={ "name": "PaymentTransactionTypeCode", @@ -10714,9 +10566,7 @@ class OtaHotelResNotifRq(BaseModel): ) class CardNumber(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) mask: Optional[str] = field( default=None, metadata={ @@ -10733,15 +10583,13 @@ class OtaHotelResNotifRq(BaseModel): "pattern": r"[0-9a-zA-Z]{1,32}", }, ) - token_provider_id: Optional[str] = ( - field( - default=None, - metadata={ - "name": "TokenProviderID", - "type": "Attribute", - "min_length": 1, - }, - ) + token_provider_id: Optional[str] = field( + default=None, + metadata={ + "name": "TokenProviderID", + "type": "Attribute", + "min_length": 1, + }, ) class BankAcct(BaseModel): @@ -10764,9 +10612,7 @@ class OtaHotelResNotifRq(BaseModel): ) class BankAcctNumber(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) plain_text: str = field( metadata={ "name": "PlainText", @@ -11044,9 +10890,7 @@ class OtaHotelResNotifRq(BaseModel): ) class CountryName(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) code: str = field( metadata={ "name": "Code", @@ -11124,14 +10968,12 @@ class OtaHotelResNotifRs(BaseModel): "type": "Element", }, ) - hotel_reservations: Optional["OtaHotelResNotifRs.HotelReservations"] = ( - field( - default=None, - metadata={ - "name": "HotelReservations", - "type": "Element", - }, - ) + hotel_reservations: Optional["OtaHotelResNotifRs.HotelReservations"] = field( + default=None, + metadata={ + "name": "HotelReservations", + "type": "Element", + }, ) version: object = field( metadata={ @@ -11874,12 +11716,14 @@ class OtaResRetrieveRs(BaseModel): class HotelReservation(BaseModel): model_config = ConfigDict(defer_build=True) - unique_id: "OtaResRetrieveRs.ReservationsList.HotelReservation.UniqueId" = field( - metadata={ - "name": "UniqueID", - "type": "Element", - "required": True, - } + unique_id: "OtaResRetrieveRs.ReservationsList.HotelReservation.UniqueId" = ( + field( + metadata={ + "name": "UniqueID", + "type": "Element", + "required": True, + } + ) ) room_stays: Optional[ "OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays" @@ -12183,22 +12027,22 @@ class OtaResRetrieveRs(BaseModel): class MealsIncluded(BaseModel): model_config = ConfigDict(defer_build=True) - meal_plan_indicator: MealsIncludedMealPlanIndicator = field( - metadata={ - "name": "MealPlanIndicator", - "type": "Attribute", - "required": True, - } - ) - meal_plan_codes: MealsIncludedMealPlanCodes = ( + meal_plan_indicator: MealsIncludedMealPlanIndicator = ( field( metadata={ - "name": "MealPlanCodes", + "name": "MealPlanIndicator", "type": "Attribute", "required": True, } ) ) + meal_plan_codes: MealsIncludedMealPlanCodes = field( + metadata={ + "name": "MealPlanCodes", + "type": "Attribute", + "required": True, + } + ) class RoomRates(BaseModel): model_config = ConfigDict(defer_build=True) @@ -12279,9 +12123,7 @@ class OtaResRetrieveRs(BaseModel): "pattern": r"\S+", }, ) - expire_date_exclusive_ind: Optional[ - str - ] = field( + expire_date_exclusive_ind: Optional[str] = field( default=None, metadata={ "name": "ExpireDateExclusiveInd", @@ -12289,9 +12131,7 @@ class OtaResRetrieveRs(BaseModel): "pattern": r"\S+", }, ) - rate_time_unit: Optional[ - RateRateTimeUnit - ] = field( + rate_time_unit: Optional[RateRateTimeUnit] = field( default=None, metadata={ "name": "RateTimeUnit", @@ -12308,19 +12148,15 @@ class OtaResRetrieveRs(BaseModel): ) class Base(BaseModel): - model_config = ConfigDict( - defer_build=True - ) - amount_after_tax: Optional[str] = ( - field( - default=None, - metadata={ - "name": "AmountAfterTax", - "type": "Attribute", - "min_exclusive": "0.0", - "pattern": r"[0-9]*\.?[0-9]*", - }, - ) + model_config = ConfigDict(defer_build=True) + amount_after_tax: Optional[str] = field( + default=None, + metadata={ + "name": "AmountAfterTax", + "type": "Attribute", + "min_exclusive": "0.0", + "pattern": r"[0-9]*\.?[0-9]*", + }, ) currency_code: Optional[str] = field( default=None, @@ -12485,9 +12321,7 @@ class OtaResRetrieveRs(BaseModel): ) class CardNumber(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) plain_text: Optional[str] = field( default=None, metadata={ @@ -12504,15 +12338,13 @@ class OtaResRetrieveRs(BaseModel): "min_length": 1, }, ) - encryption_method: Optional[str] = ( - field( - default=None, - metadata={ - "name": "EncryptionMethod", - "type": "Attribute", - "min_length": 1, - }, - ) + encryption_method: Optional[str] = field( + default=None, + metadata={ + "name": "EncryptionMethod", + "type": "Attribute", + "min_length": 1, + }, ) class Total(BaseModel): @@ -12940,9 +12772,7 @@ class OtaResRetrieveRs(BaseModel): ) class PersonName(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) name_prefix: Optional[str] = field( default=None, metadata={ @@ -12981,9 +12811,7 @@ class OtaResRetrieveRs(BaseModel): ) class Telephone(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) phone_tech_type: Optional[str] = field( default=None, metadata={ @@ -13002,9 +12830,7 @@ class OtaResRetrieveRs(BaseModel): ) class Email(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) value: str = field( default="", metadata={ @@ -13022,9 +12848,7 @@ class OtaResRetrieveRs(BaseModel): ) class Address(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) address_line: Optional[str] = field( default=None, metadata={ @@ -13071,9 +12895,7 @@ class OtaResRetrieveRs(BaseModel): ) class CountryName(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) code: str = field( metadata={ "name": "Code", @@ -13370,9 +13192,7 @@ class OtaResRetrieveRs(BaseModel): "type": "Attribute", }, ) - payment_transaction_type_code: Optional[ - object - ] = field( + payment_transaction_type_code: Optional[object] = field( default=None, metadata={ "name": "PaymentTransactionTypeCode", @@ -13418,9 +13238,7 @@ class OtaResRetrieveRs(BaseModel): ) class CardNumber(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) mask: Optional[str] = field( default=None, metadata={ @@ -13437,15 +13255,13 @@ class OtaResRetrieveRs(BaseModel): "pattern": r"[0-9a-zA-Z]{1,32}", }, ) - token_provider_id: Optional[str] = ( - field( - default=None, - metadata={ - "name": "TokenProviderID", - "type": "Attribute", - "min_length": 1, - }, - ) + token_provider_id: Optional[str] = field( + default=None, + metadata={ + "name": "TokenProviderID", + "type": "Attribute", + "min_length": 1, + }, ) class BankAcct(BaseModel): @@ -13468,9 +13284,7 @@ class OtaResRetrieveRs(BaseModel): ) class BankAcctNumber(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) plain_text: str = field( metadata={ "name": "PlainText", @@ -13748,9 +13562,7 @@ class OtaResRetrieveRs(BaseModel): ) class CountryName(BaseModel): - model_config = ConfigDict( - defer_build=True - ) + model_config = ConfigDict(defer_build=True) code: str = field( metadata={ "name": "Code", diff --git a/src/main.py b/src/main.py index 42eef3b..0383495 100644 --- a/src/main.py +++ b/src/main.py @@ -6,26 +6,9 @@ from datetime import datetime, timezone import re from xsdata_pydantic.bindings import XmlSerializer -def validate_gender(gender: str) -> str: - """Validate gender field against the pattern (Unknown|Male|Female)""" - if gender and not re.match(r"^(Unknown|Male|Female)$", gender): - raise ValueError(f"Invalid gender value: '{gender}'. Must be one of: Unknown, Male, Female") - return gender +from simplified_access import CustomerData, CustomerFactory, PhoneTechType + -def validate_dataclass_patterns(obj) -> None: - """Custom validation function to check pattern constraints""" - # Add validation for known pattern fields - if hasattr(obj, 'gender') and obj.gender: - validate_gender(obj.gender) - - # Recursively validate nested objects - for field_name, field_value in vars(obj).items(): - if hasattr(field_value, '__dataclass_fields__'): - validate_dataclass_patterns(field_value) - elif isinstance(field_value, list): - for item in field_value: - if hasattr(item, '__dataclass_fields__'): - validate_dataclass_patterns(item) def main(): # Success - use None instead of object() for cleaner XML output @@ -33,41 +16,70 @@ def main(): # UniqueID unique_id = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.UniqueId( - type_value=ab.UniqueIdType2.VALUE_14, - id="6b34fe24ac2ff811" + type_value=ab.UniqueIdType2.VALUE_14, id="6b34fe24ac2ff811" ) # TimeSpan - use the actual nested class - time_span = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay.TimeSpan() + + start_date_window = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay.TimeSpan.StartDateWindow( + earliest_date="2024-10-01", latest_date="2024-10-02" + ) + + time_span = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay.TimeSpan( + start_date_window=start_date_window + ) # RoomStay with TimeSpan - room_stay = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay( - time_span=time_span + room_stay = ( + ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays.RoomStay( + time_span=time_span + ) ) room_stays = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.RoomStays( room_stay=[room_stay] ) + customer_data = CustomerData( + given_name="John", + surname="Doe", + name_prefix="Mr.", + phone_numbers=[ + ("+1234567890", PhoneTechType.MOBILE), # Phone number with type + ("+0987654321", None) # Phone number without type + ], + email_address="john.doe@example.com", + email_newsletter=True, + address_line="123 Main Street", + city_name="Anytown", + postal_code="12345", + country_code="US", + address_catalog=False, + gender="Male", + birth_date="1980-01-01", + language="en" + ) + + retrieve_customer = CustomerFactory.create_retrieve_customer(customer_data) + profile = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile( - customer=ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer( - person_name=ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer.PersonName( - given_name="John", - surname="Doe" - ) - ) + customer=retrieve_customer ) # Use the actual nested Profiles class - profile_info = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo( - profile=profile) + profile=profile + ) - profiles = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest.Profiles(profile_info=profile_info) + profiles = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest.Profiles( + profile_info=profile_info + ) # ResGuest - res_guest = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest( - profiles=profiles + res_guest = ( + ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest( + profiles=profiles + ) ) res_guests = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests( res_guest=res_guest @@ -75,19 +87,23 @@ def main(): # Use the actual nested HotelReservationIds class hotel_res_ids = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.HotelReservationIds( - hotel_reservation_id=[] + hotel_reservation_id = [ + ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.HotelReservationIds.HotelReservationId( + res_id_type="13", res_id_source_context="99tales" + ) + ] ) # Basic property info basic_property_info = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo.BasicPropertyInfo( - hotel_code="123", - hotel_name="Frangart Inn" + hotel_code="123", hotel_name="Frangart Inn" ) # ResGlobalInfo - res_global_info = ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo( - hotel_reservation_ids=hotel_res_ids, - basic_property_info=basic_property_info + res_global_info = ( + ab.OtaResRetrieveRs.ReservationsList.HotelReservation.ResGlobalInfo( + hotel_reservation_ids=hotel_res_ids, basic_property_info=basic_property_info + ) ) # Hotel Reservation @@ -98,16 +114,16 @@ def main(): unique_id=unique_id, room_stays=room_stays, res_guests=res_guests, - res_global_info=res_global_info + res_global_info=res_global_info, ) - reservations_list = ab.OtaResRetrieveRs.ReservationsList(hotel_reservation=[hotel_reservation]) + reservations_list = ab.OtaResRetrieveRs.ReservationsList( + hotel_reservation=[hotel_reservation] + ) # Root element ota_res_retrieve_rs = ab.OtaResRetrieveRs( - version="7.000", - success=success, - reservations_list=reservations_list + version="7.000", success=success, reservations_list=reservations_list ) # Serialize using Pydantic's model_dump and convert to XML @@ -115,46 +131,49 @@ def main(): # First validate the model ota_res_retrieve_rs.model_validate(ota_res_retrieve_rs.model_dump()) print("āœ… Pydantic validation successful!") - + # For XML serialization with Pydantic models, we need to use xsdata-pydantic serializer from xsdata.formats.dataclass.serializers.config import SerializerConfig - + config = SerializerConfig( - pretty_print=True, - xml_declaration=True, - encoding="UTF-8" + pretty_print=True, xml_declaration=True, encoding="UTF-8" ) - + serializer = XmlSerializer(config=config) - + # Use ns_map to control namespace prefixes - set default namespace ns_map = {None: "http://www.opentravel.org/OTA/2003/05"} xml_string = serializer.render(ota_res_retrieve_rs, ns_map=ns_map) - - with open('output.xml', 'w', encoding='utf-8') as outfile: + + with open("output.xml", "w", encoding="utf-8") as outfile: outfile.write(xml_string) - + print("āœ… XML serialization successful!") print(f"Generated XML written to output.xml") - + # Also print the pretty formatted XML to console print("\nšŸ“„ Generated XML:") print(xml_string) # Test parsing back from xsdata_pydantic.bindings import XmlParser + parser = XmlParser() - - with open('output.xml', 'r', encoding='utf-8') as infile: + + with open("output.xml", "r", encoding="utf-8") as infile: xml_content = infile.read() - + parsed_result = parser.from_string(xml_content, ab.OtaResRetrieveRs) - print("āœ… Round-trip validation successful!") - print(f"Parsed reservation status: {parsed_result.reservations_list.hotel_reservation[0].res_status}") + + print("āœ… Round-trip validation successful!") + print( + f"Parsed reservation status: {parsed_result.reservations_list.hotel_reservation[0].res_status}" + ) + except Exception as e: print(f"āŒ Validation/Serialization failed: {e}") if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/src/output.xml b/src/output.xml index 8b22f0d..5dc9741 100644 --- a/src/output.xml +++ b/src/output.xml @@ -1,11 +1,13 @@ - + - + + + @@ -13,11 +15,21 @@ - + + Mr. John Doe + + + john.doe@example.com +
+ 123 Main Street + Anytown + 12345 + +
@@ -25,7 +37,9 @@
- + + +
diff --git a/src/simplified_access.py b/src/simplified_access.py new file mode 100644 index 0000000..05134fb --- /dev/null +++ b/src/simplified_access.py @@ -0,0 +1,230 @@ +from typing import Union, Optional, Any, TypeVar +from pydantic import BaseModel, ConfigDict, Field +from dataclasses import dataclass +from enum import Enum + +# Import the generated classes +from generated.alpinebits import OtaHotelResNotifRq, OtaResRetrieveRs + +# Define type aliases for the two Customer types +NotifCustomer = OtaHotelResNotifRq.HotelReservations.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer +RetrieveCustomer = OtaResRetrieveRs.ReservationsList.HotelReservation.ResGuests.ResGuest.Profiles.ProfileInfo.Profile.Customer + + +# phonetechtype enum 1,3,5 voice, fax, mobile +class PhoneTechType(Enum): + VOICE = "1" + FAX = "3" + MOBILE = "5" + + + + +@dataclass +class CustomerData: + """Simple data class to hold customer information without nested type constraints.""" + given_name: str + surname: str + name_prefix: None | str = None + name_title: None | str = None + phone_numbers: list[tuple[str, None | PhoneTechType]] = None # (phone_number, phone_tech_type) + email_address: None | str = None + email_newsletter: None | bool = None # True for "yes", False for "no", None for not specified + address_line: None | str = None + city_name: None | str = None + postal_code: None | str = None + country_code: None | str = None # Two-letter country code + address_catalog: None | bool = None # True for "yes", False for "no", None for not specified + gender: None | str = None # "Unknown", "Male", "Female" + birth_date: None | str = None + language: None | str = None # Two-letter language code + + def __post_init__(self): + if self.phone_numbers is None: + self.phone_numbers = [] + + +class CustomerFactory: + """Factory class to create Customer instances for both OtaHotelResNotifRq and OtaResRetrieveRs.""" + + @staticmethod + def create_notif_customer(data: CustomerData) -> NotifCustomer: + """Create a Customer for OtaHotelResNotifRq.""" + return CustomerFactory._create_customer(NotifCustomer, data) + + @staticmethod + def create_retrieve_customer(data: CustomerData) -> RetrieveCustomer: + """Create a Customer for OtaResRetrieveRs.""" + return CustomerFactory._create_customer(RetrieveCustomer, data) + + @staticmethod + def _create_customer(customer_class: type, data: CustomerData) -> Any: + """Internal method to create a customer of the specified type.""" + + # Create PersonName + person_name = customer_class.PersonName( + given_name=data.given_name, + surname=data.surname, + name_prefix=data.name_prefix, + name_title=data.name_title + ) + + # Create telephone list + telephones = [] + for phone_number, phone_tech_type in data.phone_numbers: + telephone = customer_class.Telephone( + phone_number=phone_number, + phone_tech_type=phone_tech_type.value if phone_tech_type else None + ) + telephones.append(telephone) + + # Create email if provided + email = None + if data.email_address: + remark = None + if data.email_newsletter is not None: + remark = f"newsletter:{'yes' if data.email_newsletter else 'no'}" + + email = customer_class.Email( + value=data.email_address, + remark=remark + ) + + # Create address if any address fields are provided + address = None + if any([data.address_line, data.city_name, data.postal_code, data.country_code]): + country_name = None + if data.country_code: + country_name = customer_class.Address.CountryName(code=data.country_code) + + address_remark = None + if data.address_catalog is not None: + address_remark = f"catalog:{'yes' if data.address_catalog else 'no'}" + + address = customer_class.Address( + address_line=data.address_line, + city_name=data.city_name, + postal_code=data.postal_code, + country_name=country_name, + remark=address_remark + ) + + # Create the customer + return customer_class( + person_name=person_name, + telephone=telephones, + email=email, + address=address, + gender=data.gender, + birth_date=data.birth_date, + language=data.language + ) + + @staticmethod + def from_notif_customer(customer: NotifCustomer) -> CustomerData: + """Convert a NotifCustomer back to CustomerData.""" + return CustomerFactory._customer_to_data(customer) + + @staticmethod + def from_retrieve_customer(customer: RetrieveCustomer) -> CustomerData: + """Convert a RetrieveCustomer back to CustomerData.""" + return CustomerFactory._customer_to_data(customer) + + @staticmethod + def _customer_to_data(customer: Any) -> CustomerData: + """Internal method to convert any customer type to CustomerData.""" + + # Extract phone numbers + phone_numbers = [] + if customer.telephone: + for tel in customer.telephone: + phone_numbers.append((tel.phone_number, tel.phone_tech_type)) + + # Extract email info + email_address = None + email_newsletter = None + if customer.email: + email_address = customer.email.value + if customer.email.remark: + if "newsletter:yes" in customer.email.remark: + email_newsletter = True + elif "newsletter:no" in customer.email.remark: + email_newsletter = False + + # Extract address info + address_line = None + city_name = None + postal_code = None + country_code = None + address_catalog = None + + if customer.address: + address_line = customer.address.address_line + city_name = customer.address.city_name + postal_code = customer.address.postal_code + + if customer.address.country_name: + country_code = customer.address.country_name.code + + if customer.address.remark: + if "catalog:yes" in customer.address.remark: + address_catalog = True + elif "catalog:no" in customer.address.remark: + address_catalog = False + + return CustomerData( + given_name=customer.person_name.given_name, + surname=customer.person_name.surname, + name_prefix=customer.person_name.name_prefix, + name_title=customer.person_name.name_title, + phone_numbers=phone_numbers, + email_address=email_address, + email_newsletter=email_newsletter, + address_line=address_line, + city_name=city_name, + postal_code=postal_code, + country_code=country_code, + address_catalog=address_catalog, + gender=customer.gender, + birth_date=customer.birth_date, + language=customer.language + ) + + +# Usage examples +if __name__ == "__main__": + # Create customer data using simple data class + customer_data = CustomerData( + given_name="John", + surname="Doe", + name_prefix="Mr.", + phone_numbers=[ + ("+1234567890", PhoneTechType.MOBILE), # Phone number with type + ("+0987654321", None) # Phone number without type + ], + email_address="john.doe@example.com", + email_newsletter=True, + address_line="123 Main Street", + city_name="Anytown", + postal_code="12345", + country_code="US", + address_catalog=False, + gender="Male", + birth_date="1980-01-01", + language="en" + ) + + # Create customer for OtaHotelResNotifRq + notif_customer = CustomerFactory.create_notif_customer(customer_data) + print("Created NotifCustomer:", notif_customer.person_name.given_name, notif_customer.person_name.surname) + + # Create customer for OtaResRetrieveRs + retrieve_customer = CustomerFactory.create_retrieve_customer(customer_data) + print("Created RetrieveCustomer:", retrieve_customer.person_name.given_name, retrieve_customer.person_name.surname) + + # Convert back to data class + converted_data = CustomerFactory.from_notif_customer(notif_customer) + print("Converted back to data:", converted_data.given_name, converted_data.surname) + + # Verify they contain the same information + print("Original and converted data match:", customer_data == converted_data) \ No newline at end of file diff --git a/uv.lock b/uv.lock index b629a27..f494359 100644 --- a/uv.lock +++ b/uv.lock @@ -9,6 +9,7 @@ source = { virtual = "." } dependencies = [ { name = "generateds" }, { name = "lxml" }, + { name = "ruff" }, { name = "xsdata", extra = ["cli", "lxml", "soap"] }, { name = "xsdata-pydantic", extra = ["cli", "lxml", "soap"] }, ] @@ -17,6 +18,7 @@ dependencies = [ requires-dist = [ { name = "generateds", specifier = ">=2.44.3" }, { name = "lxml", specifier = ">=6.0.1" }, + { name = "ruff", specifier = ">=0.13.1" }, { name = "xsdata", extras = ["cli", "lxml", "soap"], specifier = ">=25.7" }, { name = "xsdata-pydantic", extras = ["cli", "lxml", "soap"], specifier = ">=24.5" }, ]