from typing import Optional from pydantic import BaseModel, Field import json class PropertyReviewsSummary(BaseModel): score: float total: int class DisplayPrice(BaseModel): pass class LodgingEnrichedMessage(BaseModel): pass class FormattedMoney(BaseModel): formatted: str accessibility_label: str = Field(alias='accessibilityLabel') class DisplayPrice(BaseModel): price: FormattedMoney role: str class PriceDisplayMessage(BaseModel): line_items: list[DisplayPrice | LodgingEnrichedMessage] = Field(alias='lineItems') class PropertyPriceOption(BaseModel): formatted_display_price: str = Field(alias='formattedDisplayPrice') class PropertyPrice(BaseModel): options: list[PropertyPriceOption] display_messages: list[PriceDisplayMessage] = Field(alias='displayMessages') class Coordinates(BaseModel): latitude: float longitude: float class MapMarker(BaseModel): coordinates: Coordinates = Field(alias='latLong') class DistanceFromDestination(BaseModel): unit: str value: float class DestinationInfo(BaseModel): distance_from_destination: DistanceFromDestination = Field(alias='distanceFromDestination') class Image(BaseModel): url: str class PropertyImage(BaseModel): image: Image class Property(BaseModel): id: int name: str property_image: PropertyImage = Field(alias='propertyImage') destination_info: DestinationInfo = Field(alias='destinationInfo') map_marker: MapMarker = Field(alias='mapMarker') price: PropertyPrice reviews: PropertyReviewsSummary @property def property_price_per_night(self) -> str: try: price_per_night = [j_price for j_price in self.price.display_messages[0].line_items if j_price.role == 'LEAD' ][0].price.accessibility_label except IndexError: price_per_night = 'Index Error' return price_per_night @property def reviews_score(self) -> float: return self.reviews.score @property def reviews_amount(self) -> int: return self.reviews.total class PropertySearch(BaseModel): properties: list[Property] class Data(BaseModel): property_search: PropertySearch = Field(alias='propertySearch') class ApiResponse(BaseModel): data: Data if __name__ == "__main__": with open('properties_v2_list_example.json', 'r', encoding='utf-8') as json_file: data = json.load(json_file) results = ApiResponse(**data) # print('\n\n***\n\n'.join(str(i) for i in results.data.property_search.properties)) for i_property in results.data.property_search.properties: property_price_per_night = i_property.property_price_per_night property_rating_str = f'The score is {i_property.reviews_score} based on {i_property.reviews_amount} reviews' print( f''' Property: {i_property.name} (id: {i_property.id}) {property_price_per_night} per night {property_rating_str} ''' )