使用 telegram bot 返回 matplotlib 绘图

2023-12-29

这段代码来自here https://djangostars.com/blog/how-to-create-and-deploy-a-telegram-bot/我正在构建的电报机器人有以下代码:

import pandas as pd
from pandas import datetime
from pandas import DataFrame as df
import matplotlib
from pandas_datareader import data as web
import matplotlib.pyplot as plt
import datetime
import requests 

from bottle import (  
    run, post, response, request as bottle_request
)

BOT_URL = 'https://api.telegram.org/bot128secretns/'  
def get_chat_id(data):  
    """
    Method to extract chat id from telegram request.
    """
    chat_id = data['message']['chat']['id']

    return chat_id

def get_message(data):  
    """
    Method to extract message id from telegram request.
    """
    message_text = data['message']['text']

    return message_text

def send_message(prepared_data):  
    """
    Prepared data should be json which includes at least `chat_id` and `text`
    """ 
    message_url = BOT_URL + 'sendMessage'
    requests.post(message_url, json=prepared_data)   

def get_ticker(text):  
    stock = f'^GSPC'
    start = datetime.date(2000,1,1)
    end = datetime.date.today()
    data = web.DataReader(stock, 'yahoo',start, end)
    plot = data.plot(y='Open') 
    return plot


def prepare_data_for_answer(data):  
    answer = get_ticker(get_message(data))

    json_data = {
        "chat_id": get_chat_id(data),
        "text": answer,
    }

    return json_data

@post('/')
def main():  
    data = bottle_request.json

    answer_data = prepare_data_for_answer(data)
    send_message(answer_data)  # <--- function for sending answer

    return response  # status 200 OK by default

if __name__ == '__main__':  
    run(host='localhost', port=8080, debug=True)

当我运行此代码时,我收到以下错误:

TypeError: Object of type AxesSubplot is not JSON serializable

这段代码的作用是从电报应用程序中获取股票代码并返回其图表。

我知道这是因为 json 不处理图像。 我可以做什么来解决它?


抱歉,我参加聚会有点晚了。下面是一个可能的解决方案,尽管我没有测试它。希望它有效,或者至少为您提供解决问题的方法:)

import datetime
from io import BytesIO

import requests
from pandas_datareader import data as web
from bottle import (
    run, post, response, request as bottle_request
)

BOT_URL = 'https://api.telegram.org/bot128secretns/'

def get_chat_id(data):
    """
    Method to extract chat id from telegram request.
    """
    chat_id = data['message']['chat']['id']

    return chat_id

def get_message(data):
    """
    Method to extract message id from telegram request.
    """
    message_text = data['message']['text']

    return message_text

def send_photo(prepared_data):
    """
    Prepared data should be json which includes at least `chat_id` and `plot_file`
    """
    data = {'chat_id': prepared_data['chat_id']}
    files = {'photo': prepared_data['plot_file']}

    requests.post(BOT_URL + 'sendPhoto', json=data, files=files)

def get_ticker(text):
    stock = f'^GSPC'
    start = datetime.date(2000,1,1)
    end = datetime.date.today()
    data = web.DataReader(stock, 'yahoo',start, end)
    plot = data.plot(y='Open')

    return plot

def prepare_data_for_answer(data):
    plot = get_ticker(get_message(data))

    # Write the plot Figure to a file-like bytes object:
    plot_file = BytesIO()
    fig = plot.get_figure()
    fig.savefig(plot_file, format='png')
    plot_file.seek(0)

    prepared_data = {
        "chat_id": get_chat_id(data),
        "plot_file": plot_file,
    }

    return prepared_data

@post('/')
def main():
    data = bottle_request.json

    answer_data = prepare_data_for_answer(data)
    send_photo(answer_data)  # <--- function for sending answer

    return response  # status 200 OK by default

if __name__ == '__main__':
    run(host='localhost', port=8080, debug=True)

这个想法不是使用发送消息sendMessageTelegram API 端点,但要使用sendPhoto端点。在这里,我们使用savefig调用prepare_data_for_answer要转换的函数体AxesSubplot实例,我们从get_ticker函数,到类似文件BytesIO对象,然后我们使用该对象将其作为照片发送到 Telegramsend_photo函数(以前命名为send_message).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 telegram bot 返回 matplotlib 绘图 的相关文章

随机推荐