Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c797cac291 | |||
| 6510a001f2 | |||
| a802613778 | |||
| ec9659d51e | |||
| ee2b18bdb5 | |||
| 9335b782c2 | |||
| 1df9a16643 | |||
| 29ceb95404 | |||
| 9924f0eebb | |||
| 2de77f7c8a | |||
| ff5952624d |
2
.gitignore
vendored
2
.gitignore
vendored
@ -160,3 +160,5 @@ cython_debug/
|
|||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
|
# Configuration file
|
||||||
|
config.ini
|
||||||
|
|||||||
23
db.py
Normal file
23
db.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import psycopg2
|
||||||
|
|
||||||
|
|
||||||
|
class PostgreSQLDatabase:
|
||||||
|
def __init__(self, host, database, user, password):
|
||||||
|
self.__host = host
|
||||||
|
self.__database = database
|
||||||
|
self.__user = user
|
||||||
|
self.__password = password
|
||||||
|
|
||||||
|
def execute_query(self, query):
|
||||||
|
connection = psycopg2.connect(
|
||||||
|
host=self.__host,
|
||||||
|
database=self.__database,
|
||||||
|
user=self.__user,
|
||||||
|
password=self.__password
|
||||||
|
)
|
||||||
|
cursor = connection.cursor()
|
||||||
|
cursor.execute(query)
|
||||||
|
result = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
return result
|
||||||
78
main.py
Normal file
78
main.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import telebot
|
||||||
|
from telebot import types
|
||||||
|
import configparser
|
||||||
|
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read('config.ini')
|
||||||
|
|
||||||
|
TG_TOKEN = config.get('telebot', 'token')
|
||||||
|
API_TOKEN = config.get('hotels_api', 'token')
|
||||||
|
DB_HOST = config.get('database', 'host')
|
||||||
|
DB_PORT = config.get('database', 'port')
|
||||||
|
DB_DATABASE = config.get('database', 'database')
|
||||||
|
DB_USER = config.get('database', 'user')
|
||||||
|
DB_PASSWORD = config.get('database', 'password')
|
||||||
|
|
||||||
|
bot = telebot.TeleBot(token=TG_TOKEN)
|
||||||
|
last_commands = {}
|
||||||
|
|
||||||
|
|
||||||
|
@bot.message_handler(commands=['start', 'help'])
|
||||||
|
def handle_start(message):
|
||||||
|
pass # TODO add logic for handling the start and help commands
|
||||||
|
|
||||||
|
|
||||||
|
@bot.message_handler(commands=['lowprice'])
|
||||||
|
def handle_lowprice(message):
|
||||||
|
last_commands[message.chat.id] = 'lowprice'
|
||||||
|
|
||||||
|
# Create InlineKeyboardMarkup with buttons
|
||||||
|
keyboard = types.InlineKeyboardMarkup(row_width=5)
|
||||||
|
buttons = [types.InlineKeyboardButton(str(i), callback_data=str(i)) for i in range(1, 11)]
|
||||||
|
keyboard.add(*buttons)
|
||||||
|
|
||||||
|
# Send keyboard with buttons
|
||||||
|
bot.send_message(message.chat.id, 'Выберите количество:', reply_markup=keyboard)
|
||||||
|
|
||||||
|
|
||||||
|
@bot.message_handler(commands=['highprice'])
|
||||||
|
def handle_highprice(message):
|
||||||
|
last_commands[message.chat.id] = 'highprice'
|
||||||
|
|
||||||
|
# Create InlineKeyboardMarkup with buttons
|
||||||
|
keyboard = types.InlineKeyboardMarkup(row_width=5)
|
||||||
|
buttons = [types.InlineKeyboardButton(str(i), callback_data=str(i)) for i in range(1, 11)]
|
||||||
|
keyboard.add(*buttons)
|
||||||
|
|
||||||
|
# Send keyboard with buttons
|
||||||
|
bot.send_message(message.chat.id, 'Выберите количество:', reply_markup=keyboard)
|
||||||
|
|
||||||
|
|
||||||
|
@bot.message_handler(commands=['bestdeal'])
|
||||||
|
def handle_bestdeal(message):
|
||||||
|
pass # TODO add logic for handling the bestdeal command
|
||||||
|
|
||||||
|
|
||||||
|
@bot.message_handler(commands=['history'])
|
||||||
|
def handle_history(message):
|
||||||
|
pass # TODO add logic for handling the history command
|
||||||
|
|
||||||
|
|
||||||
|
@bot.callback_query_handler(func=lambda call: True) # Handler for button clicks
|
||||||
|
def handle_button_click(call):
|
||||||
|
if call.message.chat.id in last_commands:
|
||||||
|
command = last_commands[call.message.chat.id] # Get the current command from the last commands dict
|
||||||
|
|
||||||
|
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id) # Remove the keyboard
|
||||||
|
|
||||||
|
# Edit the message.
|
||||||
|
bot.edit_message_text(
|
||||||
|
text=f'Вы выбрали количество: {call.data} ({last_commands[call.message.chat.id]})',
|
||||||
|
chat_id=call.message.chat.id,
|
||||||
|
message_id=call.message.message_id
|
||||||
|
)
|
||||||
|
|
||||||
|
del last_commands[call.message.chat.id] # Remove the last command state after handling
|
||||||
|
|
||||||
|
|
||||||
|
bot.polling()
|
||||||
57
pydantic_models/locations_v3_search.py
Normal file
57
pydantic_models/locations_v3_search.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
from pydantic import BaseModel, Field
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class RegionNames(BaseModel):
|
||||||
|
full_name: str = Field(alias='fullName')
|
||||||
|
short_name: str = Field(alias='shortName')
|
||||||
|
display_name: str = Field(alias='displayName')
|
||||||
|
primary_display_name: str = Field(alias='primaryDisplayName')
|
||||||
|
secondary_display_name: str = Field(alias='secondaryDisplayName')
|
||||||
|
last_search_name: str = Field(alias='lastSearchName')
|
||||||
|
|
||||||
|
|
||||||
|
class EssId(BaseModel):
|
||||||
|
source_name: str = Field(alias='sourceName')
|
||||||
|
source_id: int = Field(alias='sourceId')
|
||||||
|
|
||||||
|
|
||||||
|
class Country(BaseModel):
|
||||||
|
name: str
|
||||||
|
iso_code2: str = Field(alias='isoCode2')
|
||||||
|
iso_code3: str = Field(alias='isoCode3')
|
||||||
|
|
||||||
|
|
||||||
|
class HierarchyInfo(BaseModel):
|
||||||
|
country: Country
|
||||||
|
|
||||||
|
|
||||||
|
class Coordinates(BaseModel):
|
||||||
|
latitude: float = Field(alias='lat')
|
||||||
|
longitude: float = Field(alias='long')
|
||||||
|
|
||||||
|
|
||||||
|
class GaiaRegionResult(BaseModel):
|
||||||
|
index: int
|
||||||
|
gaia_id: int = Field(alias='gaiaId')
|
||||||
|
type: str
|
||||||
|
region_names: RegionNames = Field(alias='regionNames')
|
||||||
|
ess_id: EssId = Field(alias='essId')
|
||||||
|
coordinates: Coordinates
|
||||||
|
hierarchy_info: HierarchyInfo = Field(alias='hierarchyInfo')
|
||||||
|
|
||||||
|
|
||||||
|
class SearchResults(BaseModel):
|
||||||
|
query: str = Field(alias='q')
|
||||||
|
request_id: str = Field(alias='rid')
|
||||||
|
request_status: str = Field(alias='rc')
|
||||||
|
search_results: list[GaiaRegionResult] = Field(alias='sr')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
with open('locations_v3_search_example.json', 'r', encoding='utf-8') as json_file:
|
||||||
|
data = json.load(json_file)
|
||||||
|
results = SearchResults(**data)
|
||||||
|
print('\n'.join(
|
||||||
|
[result.region_names.full_name for result in results.search_results if result.type in ('CITY', 'NEIGHBORHOOD')])
|
||||||
|
)
|
||||||
298
pydantic_models/locations_v3_search_example.json
Normal file
298
pydantic_models/locations_v3_search_example.json
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
{
|
||||||
|
"q":"Нью Йорк",
|
||||||
|
"rid":"fbab370c153d458ea91ce8557d32fa71",
|
||||||
|
"rc":"OK",
|
||||||
|
"sr":[
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"0",
|
||||||
|
"gaiaId":"2621",
|
||||||
|
"type":"CITY",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"shortName":"Нью-Йорк",
|
||||||
|
"displayName":"Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Нью-Йорк",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Нью-Йорк"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"2621"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.712843",
|
||||||
|
"long":"-74.005966"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"1",
|
||||||
|
"gaiaId":"553248633938969338",
|
||||||
|
"type":"NEIGHBORHOOD",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Центральный Нью-Йорк, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"shortName":"Центральный Нью-Йорк",
|
||||||
|
"displayName":"Центральный Нью-Йорк, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Центральный Нью-Йорк",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Центральный Нью-Йорк"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"553248633938969338"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.759591",
|
||||||
|
"long":"-73.984912"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"2",
|
||||||
|
"gaiaId":"129440",
|
||||||
|
"type":"NEIGHBORHOOD",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Манхэттен, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"shortName":"Манхэттен",
|
||||||
|
"displayName":"Манхэттен, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Манхэттен",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Манхэттен"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"129440"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.783062",
|
||||||
|
"long":"-73.971252"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"3",
|
||||||
|
"gaiaId":"177851",
|
||||||
|
"type":"CITY",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Бруклин, Нью-Йорк, США",
|
||||||
|
"shortName":"Бруклин",
|
||||||
|
"displayName":"Бруклин, Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Бруклин",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Бруклин"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"177851"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.678177",
|
||||||
|
"long":"-73.94416"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"4",
|
||||||
|
"gaiaId":"4933194",
|
||||||
|
"type":"AIRPORT",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Нью-Йорк, Нью-Йорк, США (JFK-Джон Ф. Кеннеди, международный)",
|
||||||
|
"shortName":"Нью-Йорк, Нью-Йорк (JFK-Джон Ф. Кеннеди, международный)",
|
||||||
|
"displayName":"Нью-Йорк (JFK - Джон Ф. Кеннеди, международный), Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Нью-Йорк (JFK - Джон Ф. Кеннеди, международный)",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Нью-Йорк (JFK - Джон Ф. Кеннеди, международный)"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"4933194"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.644166",
|
||||||
|
"long":"-73.782548"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isMinorAirport":"false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"5",
|
||||||
|
"gaiaId":"6141743",
|
||||||
|
"type":"POI",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Всемирный финансовый центр, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"shortName":"Всемирный финансовый центр",
|
||||||
|
"displayName":"Всемирный финансовый центр, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Всемирный финансовый центр",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Всемирный финансовый центр"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"6141743"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.71285",
|
||||||
|
"long":"-74.014432"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"6",
|
||||||
|
"gaiaId":"6056463",
|
||||||
|
"type":"POI",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Центральный парк, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"shortName":"Центральный парк",
|
||||||
|
"displayName":"Центральный парк, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Центральный парк",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Центральный парк"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"6056463"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.78072",
|
||||||
|
"long":"-73.966802"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"7",
|
||||||
|
"gaiaId":"6004547",
|
||||||
|
"type":"NEIGHBORHOOD",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Бруклин-Хайтс, Нью-Йорк, США",
|
||||||
|
"shortName":"Бруклин-Хайтс",
|
||||||
|
"displayName":"Бруклин-Хайтс, Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Бруклин-Хайтс",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Бруклин-Хайтс"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"6004547"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.696762414204954",
|
||||||
|
"long":"-73.99526676287296"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"8",
|
||||||
|
"gaiaId":"800075",
|
||||||
|
"type":"NEIGHBORHOOD",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Верхний район Уэст-Сайд, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"shortName":"Верхний район Уэст-Сайд",
|
||||||
|
"displayName":"Верхний район Уэст-Сайд, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Верхний район Уэст-Сайд",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Верхний район Уэст-Сайд"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"800075"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.78701",
|
||||||
|
"long":"-73.975365"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type":"gaiaRegionResult",
|
||||||
|
"index":"9",
|
||||||
|
"gaiaId":"800076",
|
||||||
|
"type":"NEIGHBORHOOD",
|
||||||
|
"regionNames":{
|
||||||
|
"fullName":"Верхний район Ист-Сайд, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"shortName":"Верхний район Ист-Сайд",
|
||||||
|
"displayName":"Верхний район Ист-Сайд, Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"primaryDisplayName":"Верхний район Ист-Сайд",
|
||||||
|
"secondaryDisplayName":"Нью-Йорк, Нью-Йорк, США",
|
||||||
|
"lastSearchName":"Верхний район Ист-Сайд"
|
||||||
|
},
|
||||||
|
"essId":{
|
||||||
|
"sourceName":"GAI",
|
||||||
|
"sourceId":"800076"
|
||||||
|
},
|
||||||
|
"coordinates":{
|
||||||
|
"lat":"40.773563",
|
||||||
|
"long":"-73.956558"
|
||||||
|
},
|
||||||
|
"hierarchyInfo":{
|
||||||
|
"country":{
|
||||||
|
"name":"Соединенные Штаты",
|
||||||
|
"isoCode2":"US",
|
||||||
|
"isoCode3":"USA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
122
pydantic_models/properties_v2_list.py
Normal file
122
pydantic_models/properties_v2_list.py
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
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}
|
||||||
|
'''
|
||||||
|
)
|
||||||
9421
pydantic_models/properties_v2_list_example.json
Normal file
9421
pydantic_models/properties_v2_list_example.json
Normal file
File diff suppressed because it is too large
Load Diff
4
requirements.txt
Normal file
4
requirements.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
psycopg2
|
||||||
|
requests
|
||||||
|
pydantic
|
||||||
|
pytelegrambotapi
|
||||||
Loading…
x
Reference in New Issue
Block a user