Как с помощью команд telegram бота выводить отдельные данные погоды

import telebot
from pyowm.owm import OWM
from pyowm.utils.config import get_default_config

bot = telebot.TeleBot('1:AA')

@bot.message_handler(commands=['start'])
def hello(message):
    bot.send_message(message.chat.id, 'Добро пожаловать, я бот знающий погоду во всем мире' + '\n' +
    'Чтобы узнать погоду напишите в чат название любого города\n/help - все команды бота')
@bot.message_handler(commands=['help'])
def help(message):
    bot.send_message(message.chat.id, '/start - запуск бота\n/help - команды бота\nНапишите в чат название города для получения информации о погоде')
@bot.message_handler(content_types=['text'])
def test(message):
    try:
        place = message.text
        config_dict = get_default_config()
        config_dict['language'] = 'ru'
        owm = OWM('0...', config_dict)
        mgr = owm.weather_manager()
        observation = mgr.weather_at_place(place)
        w = observation.weather
        t = w.temperature('celsius')
        t1 = t['temp']
        t2 = t['feels_like']
        t3 = t['temp_max']
        t4 = t['temp_min']

        wi = w.wind()['speed']
        humi = w.humidity
        cl = w.clouds
        dt = w.detailed_status
        ti = w.reference_time('iso')
        pr = w.pressure['press']
        vd = w.visibility_distance
        st = w.status


        bot.send_message(message.chat.id, 'В городе ' + str(place) + ' температура ' + str(t1) + ' C' + '\n' +
                         'Максимальная температура ' + str(t3) + 'C' + '\n'+
                         'Минимальная температура ' + str(t4) + 'C' + '\n' +
                         'Ощущается как ' + str(t2) + 'C' + '\n' +
                         'Скорость ветра ' + str(wi) + 'м/с' + '\n' +
                         'Давление ' + str(pr) + 'мм.рт.ст' + '\n' +
                         'Влажность ' + str(humi) + '%' + '\n' +
                         'Видимость ' + str(vd) + 'метров' + '\n'
                         'Статус ' + str(st) + '\n' + str(dt) )

    except:
        bot.send_message(message.chat.id, ' Такой город не найден')
        print(str(message.text), '- не найден')
bot.polling(none_stop=True, interval=0)

Ответы (1 шт):

Автор решения: Violet

несмотря на правильные вопросы MyZik и passant, я всё же хочу ответить на данный вопрос:

использование @bot.message_handler(content_types=['text']) будет запускать поиск погоды для всех сообщений, будь-то город или название фрукта

для удобства я вынес получение погоды в отдельную функцию с возвратом в виде словаря:

def owm_info(place):
    config_dict = get_default_config()
    config_dict['language'] = 'ru'
    owm = OWM(owm_token, config_dict)
    mgr = owm.weather_manager()
    w = mgr.weather_at_place(place).weather
    t = w.temperature('celsius')

    temp = t['temp']
    feels_like = t['feels_like']
    temp_max = t['temp_max']
    temp_min = t['temp_min']

    wind_speed = w.wind()['speed']
    humidity = w.humidity
    clouds = w.clouds
    detailed_status = w.detailed_status
    reference_time = w.reference_time('iso')
    pressure = w.pressure['press']
    visibility_distance = w.visibility_distance
    status = w.status

    return {'temp': f'Температура: {temp} C', 'feels_like': f'Ощущается как: {feels_like} C',
            'temp_max': f'Температура / max: {temp_max} C', 'temp_min': f'Температура / min: {temp_min} C'}

дальше хэндлер на команду и метод ожидания ввода:

@bot.message_handler(commands=['tmp'])
def get_tmp(message):
    msg = bot.send_message(message.chat.id, 'напишите название любого города')
    bot.register_next_step_handler(msg, get_tmp_2)

это позволит дождаться ввода от пользователя и перейти к следующему шагу:

def get_tmp_2(message):
    w = owm_info(message.text)
    bot.send_message(message.chat.id, f'{w["temp"]}\n{w["feels_like"]}\n{w["temp_max"]}\n{w["temp_min"]}')

возврат данных о погоде в виде словаря очень удобен - можно выводить конкретные значения по понятным ключам и основной код бота не нагружать форматированием конечного сообщения для пользователя

можно сделать без ожидание ввода - "аргумент" к команде:

@bot.message_handler(commands=['temp'])
def get_temp(message):
    w = owm_info(message.text.split(maxsplit=1)[1])
    bot.send_message(message.chat.id, f'{w["temp"]}\n{w["feels_like"]}\n{w["temp_max"]}\n{w["temp_min"]}')

для этого потребуется отправить боту "/temp город"

а можно пойти ещё дальше и сделать с помощью inline кнопок:

создадим словарь с данными для кнопок - text и callack_data:

button = {'temp': 'Температура', 'feels_like': 'Ощущается как', 'temp_max': 'Температура / max', 'temp_min': 'Температура / min'}

функцию создания клавиатуры из словаря:

def kb_btn(place):
    kb = InlineKeyboardMarkup()
    btn = []
    for i in button.items():
        bt = InlineKeyboardButton(text=i[1], callback_data="['w', '" + i[0] + "', '" + place + "']")
        btn.append(bt)
    kb.add(*btn)
    return kb

и коллбэк хэндлер:

@bot.callback_query_handler(func=lambda call: True)
def inline_kb(call):
    if call.data.startswith("['w"):
        bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id,
                              text=f'{owm_info(ast.literal_eval(call.data)[2])[ast.literal_eval(call.data)[1]]}',
                              reply_markup=kb_btn(ast.literal_eval(call.data)[2]))

обратите внимание на startswith - возвращает флаг, указывающий на то, начинается ли строка с указанного префикса (callback_data="['w'...) т.к. callback_data составная - префикс, ключ словаря и город, а так же ast.literal_eval который позволит получить все части callback_data по индексам.

пожалуйста! не копируйте код в тупую, разберитесь в предоставленном вам ответе, цените время потраченное на ответ.

→ Ссылка