Я хочу создать телеграмма бота. Я клонировал некоторый репозиторий из github, и теперь я пытаюсь запустить этот проект. Я создал бота с помощью @BotFather, и он дал мне токен. Когда я пытаюсь запустить этот проект с "python3 bot.py" Я получаю ошибку ", строка 1233, в getitem повышение KeyError (ключ)" У меня есть файл config.ini, и я должен заполнить его правильно ( Я знаю это из руководства), но я действительно не понимаю, как я могу заполнить это должным образом :( Может ли кто-нибудь помочь мне, я был бы очень благодарен. Я просто хочу попробовать запустить этот бот и посмотреть, как он работает, и написать свой собственный бот в будущем.
config.ini:
[Telegram]
token=<- here I wrote my token, which I got from @BotFather
[API]
client_id= <- I don't know what should I write here
app_id= <- I don't know what should I write here
app_id= <- I don't know what should I write here
shared_key= <- I don't know what should I write here
Вместо токена я использую свой собственный токен
bot.py:
# -*- coding:utf-8 -*-
import re
from sys import path
from decimal import Decimal
from configparser import ConfigParser
from telegram import ParseMode, Emoji
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from telegram.ext.dispatcher import run_async
from mdapi import DataStorage, MDApiConnector
from fundamental import FundamentalApi
import logging
# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
# read config
config = ConfigParser()
config.read_file(open('config.ini'))
# create connectors to API
api = MDApiConnector(
client_id=config['API']['client_id'],
app_id=config['API']['app_id'],
key=config['API']['shared_key']
)
fapi = FundamentalApi()
# Create telegram poller with token from settings
up = Updater(token=config['Telegram']['token'], workers=32)
dispatcher = up.dispatcher
# start stock storage
storage = DataStorage(api)
storage.start()
# Welcome message
def start(bot, update):
msg = "Привет, {user_name}! \n\n" + \
"Меня можно спросить об акциях фондового рынка США \n" + \
"и я покажу их оценку P/E и текущую цену. \n\n" + \
"Например: расскажи об AAPL или NVDA"
# Send the message
bot.send_message(chat_id=update.message.chat_id,
text=msg.format(
user_name=update.message.from_user.first_name,
bot_name=bot.name))
@run_async
def process(bot, update):
if update.message.text.find("брокера посоветуешь") > 0:
update.message.reply_text("Лично я рекомендую EXANTE!")
return
tickers = re.findall(r'[A-Z]{1,4}', update.message.text)
msg = ""
for ticker in tickers:
stock = storage.stocks.get(ticker)
if not stock: continue
eps = fapi.request(ticker).get('EarningsShare')
if not eps:
logger.warning("Can't fetch EPS for {}".format(ticker))
continue
price = api.get_last_ohlc_bar(stock['id'])
ratio = Decimal("%.4f" % price['close']) / Decimal(eps)
msg += "{ticker} ({name}, {exchange}): EPS {eps}, P/E {ratio}, цена ${price} \n".format(
ticker = ticker,
name = stock['description'],
exchange = stock['exchange'],
ratio = "%.2f" % ratio,
price = price['close'],
eps = eps
)
if not msg:
msg = "Не удалось получить данные по тикерам из запроса :(\n" +\
"Попробуйте спросить о чем-то популярном, вроде GOOG или AAPL."
bot.send_message(chat_id=update.message.chat_id, text=msg)
if __name__ == "__main__":
# Add handlers to dispatcher
dispatcher.add_handler(CommandHandler("start", start))
dispatcher.add_handler(MessageHandler(Filters.text, process))
up.start_polling()
up.idle()
basic.py:
from datetime import datetime
import requests
class FundamentalApi():
def __init__(self):
self.cache = {}
def request(self, symbol):
now = datetime.now()
result = self.cache.get(symbol)
# if data is already stored for current day
if result and (now - result[1]).days < 1:
return result[0]
params = {
"q": "select EarningsShare from yahoo.finance.quotes where symbol = '{}'".format(symbol),
"env": "store://datatables.org/alltableswithkeys",
"format": "json"
}
url = "https://query.yahooapis.com/v1/public/yql"
response = requests.get(url, params=params)
response.raise_for_status()
data = response.json()['query']['results']['quote']
self.cache[symbol] = (data, now)
return self.cache[symbol][0]
mdapi.py:
import time
from threading import Thread
from datetime import datetime
import jwt
import requests
import logging
# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
# token expiration time in seconds
EXPIRATION = 3600
API_URL = "https://api-demo.exante.eu/md/1.0"
class MDApiConnector():
token = (None, None)
algo = "HS256"
def __init__(self, client_id, app_id, key):
self.client_id = client_id
self.app_id = app_id
self.key = key
def __get_token(self):
now = datetime.now()
# if there is token and it's not expired yet
if self.token[0] and (now - self.token[1]).total_seconds() < EXPIRATION:
return self.token[0]
claims = {
"iss": self.client_id,
"sub": self.app_id,
"aud": ["symbols", "ohlc"],
"iat": int(now.timestamp()),
"exp": int(now.timestamp()) + EXPIRATION
}
new_token = str(jwt.encode(claims, self.key, self.algo), 'utf-8')
self.token = (new_token, now)
return new_token
def __request(self, endpoint, params=None):
token = self.__get_token()
result = requests.get(API_URL + endpoint,
headers={"Authorization": "Bearer %s" % token},
params=params)
result.raise_for_status()
return result.json()
def get_stocks(self):
stocks = self.__request("/types/STOCK")
return {x['ticker']: {"id": x["id"], "exchange": x["exchange"], "description": x["description"]}
for x in stocks if x.get("country") == "US"}
def get_last_ohlc_bar(self, symbolId):
# NB: we use internal symbolId, not ticker
# 86400 (sec) - day duration
ohlc = self.__request("/ohlc/%s/86400" % symbolId, {"size": 1})
return ohlc[0]
class DataStorage(Thread):
def __init__(self, connector):
super().__init__()
self.connector = connector
self.stocks = {}
def run(self):
while True:
timeout = 15 * 60 # 15 minutes
try:
self.stocks = self.connector.get_stocks()
except Exception as e:
logger.error(e)
timeout = 30 # re-read in case of exception
time.sleep(timeout)
init.py:
# -*- coding:utf-8 -*-
import re
from sys import path
from configparser import ConfigParser
from telegram import ParseMode, Emoji
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
config = ConfigParser()
config.read_file(open('config.ini'))
# Create telegram poller with token from settings
up = Updater(token=config[‘Api’]['token'])
dispatcher = up.dispatcher
# Welcome message
def start(bot, update):
msg = "Hello {user_name}! I'm {bot_name}. Ask me about stocks!"
# Send the message
bot.send_message(chat_id=update.message.chat_id,
text=msg.format(
user_name=update.message.from_user.first_name,
bot_name=bot.name))
def process(bot, update):
msg = "I will try to show info on {tickers}"
tickers = re.findall(r'[A-Z]{1,4}', update.message.text)
bot.send_message(chat_id=update.message.chat_id,
text=msg.format(tickers=", ".join(tickers)))
def main():
# Add handlers to dispatcher
dispatcher.add_handler(CommandHandler("start", start))
dispatcher.add_handler(MessageHandler(Filters.text, process))
# Start the program
up.start_polling()
up.idle()
if __name__ == '__main__':
main()