Ошибка при попытке нажать на кнопку telegram-bot'а aiogram python
Я разработал бота, имитирующего банковскую систему. Когда пользователь отправляет команду /start, бот отвечает сообщением, к которому прикреплены две кнопки: log in, register. При попытке нажать кнопку бот выводит ошибку:
TypeError: cmd_new_account() got multiple values for argument 'state'
Traceback (most recent call last):
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 309, in _process_update
response = await self.feed_update(bot, update, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 158, in feed_update
response = await self.update.wrap_outer_middleware(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\middlewares\error.py", line 25, in __call__
return await handler(event, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\middlewares\user_context.py", line 56, in __call__
return await handler(event, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\fsm\middleware.py", line 42, in __call__
return await handler(event, data)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\event\telegram.py", line 121, in trigger
return await wrapped_inner(event, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\event\handler.py", line 43, in call
return await wrapped()
^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 276, in _listen_update
return await self.propagate_event(update_type=update_type, event=event, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 146, in propagate_event
return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 141, in _wrapped
return await self._propagate_event(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 174, in _propagate_event
response = await router.propagate_event(update_type=update_type, event=event, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 174, in _propagate_event
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 174, in _propagate_event
response = await router.propagate_event(update_type=update_type, event=event, **kwargs)
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 174, in _propagate_event
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 174, in _propagate_event
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 174, in _propagate_event
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 174, in _propagate_event
response = await router.propagate_event(update_type=update_type, event=event, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 146, in propagate_event
return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 141, in _wrapped
return await self._propagate_event(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\router.py", line 166, in _propagate_event
response = await observer.trigger(event, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\event\telegram.py", line 121, in trigger
return await wrapped_inner(event, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\информатика\программы на Python\iogram\tg bot on aiogramm 2.0\venv\Lib\site-packages\aiogram\dispatcher\event\handler.py", line 43, in call
return await wrapped()
^^^^^^^^^
TypeError: cmd_new_account() got multiple values for argument 'state'
Вот мой код:
main
import asyncio
from aiogram import Bot, Dispatcher, F
from app.handlers import router, manager
async def main():
bot = Bot(token='token')
dp = Dispatcher() #dispatcher занимается обновлениями, если происходит какое-либо событие оно попадает в него
dp.include_router(router)
await dp.start_polling(bot) #bot каждую секунду обращается к серверу телеграм, проверяя произошло ли какое либо обновление(например сообщение)
if __name__ == '__main__': #запуск функции только в том случае, если запущенн именно данный файл. Если данный файл импортирован, то что внутри запускаться не будет
print('bot_on')
try:
asyncio.run(main())
except KeyboardInterrupt:
manager.connection_close()
print('bot off')
handlers
from aiogram import Router, F
from aiogram.types import Message, CallbackQuery
from aiogram.filters import CommandStart, Command
from aiogram.filters.state import State, StatesGroup
from aiogram.fsm.context import FSMContext
import app.keyboards as kb
from app.managment_database import*
from app.Bank import *
router = Router()
bank = Bank()
class Form(StatesGroup):
unknown_user = State()
get_new_account_password = State()
create_new_account = State()
get_account_number = State()
get_account_password = State()
account_managment = State()
@router.message(CommandStart())
async def cmd_start(message: Message, state:FSMContext):
#await state.clear()
await message.reply('Здравствуйте! Что вы хотите сделать?', reply_markup=kb.catalog_unknown)
await state.set_state(Form.unknown_user)
@router.callback_query(F.data == 'register', Form.unknown_user)
async def cmd_new_account(state: FSMContext):
await state.set_state(Form.get_new_account_password)
@router.message(F.text, Form.get_new_account_password)
async def get_new_account_password(message:Message, state:FSMContext):
await message.answer('Придумайте пароль')
await state.set_state(Form.create_new_account)
@router.message(F.text, Form.create_new_account)
async def new_account(message:Message, state:FSMContext):
await state.update_data(password=message.text)
await message.answer('Создание аккаунта...')
id = message.from_user.id
data = await state.get_data()
answer = bank.new_account(id, data.get('password'))
await message.answer(answer)
await state.clear()
await state.set_state(Form.account_managment)
await message.answer('Что вы хотите сделать?', reply_markup=kb.catalog_logged)
@router.callback_query(F.data == 'log_in', Form.unknown_user)
async def cmd_log_in(message:Message, state:FSMContext):
await message.answer('Введите номер аккаунта')
await state.set_state(Form.get_account_number)
@router.message(F.text, Form.get_account_number)
async def get_account_number(message:Message, state:FSMContext):
await state.update_data(account_number=message.text)
await message.answer('Введите пароль')
await state.set_state(Form.get_account_password)
@router.message(F.text, Form.get_account_password)
async def get_account_password(message:Message, state:FSMContext):
await state.update_data(account_password=message.text)
await message.answer('Вход в аккаунт...')
id = message.from_user.id
data = await state.get_data()
answer = bank.log_in_account(id, data['account_number'], data['account_password'])
await message.answer(answer)
await state.clear()
await state.set_state(Form.account_managment)
await message.answer('Что вы хотите сделать?', reply_markup=kb.catalog_logged)
Bank
from app.Account import *
from app.managment_database import *
manager = Manager()
class Bank:
def __init__(self):
#self.accounts_dict = {}
self.next_account_number = manager.get_account_number()
def new_account(self, id, user_password):
print('bank connect')
new_account_number = self.next_account_number
manager.add_data(id, new_account_number, user_password, 0)
self.next_account_number += 1
return f'You account number: {new_account_number}'
def close_account(self, id, user_account_number, user_password):
account_password, account_balance = manager.search_user(id, user_account_number)
if account_password == user_password:
manager.delete_data(id, user_account_number)
if account_balance != 0:
return f'\nYou had {account_balance} in your account, which is being returned to you.\nYour account is now closed'
return f'Your account is now closed'
else:
return f'Error!'
def log_in_account(self, id, user_account_number, user_password):
account_password, account_balance = manager.search_user(id, user_account_number)
if account_password == user_password:
return f'Вы вошли в аккаунт {user_account_number}. На вашем балансе: {account_balance} rub'
else:
return f'Error!'
def deposit(self, id, user_account_number, user_amount):
account_password, account_balance = manager.search_user(id, user_account_number)
manager.update_data(id, user_account_number, user_amount + account_balance)
return f'You balance: {user_amount + account_balance}'
def withdraw(self, id, user_account_number, user_amount):
account_password, account_balance = manager.search_user(id, user_account_number)
manager.update_data(id, user_account_number, account_balance - user_amount)
return f'You balance: {account_balance - user_amount}'
def get_balance(self, id, user_account_number):
account_password, account_balance = manager.search_user(id, user_account_number)
return f'\nYou balance: {account_balance}\n'
manager_database
import sqlite3
class Manager():
def __init__(self):
self.connection = sqlite3.connect('app\Database.bd')
self.cursor = self.connection.cursor()
self.cursor.execute('''CREATE TABLE IF NOT EXISTS Users (
id INTEGER,
account_number INTEGER,
password TEXT NOT NULL,
balance INTEGER
)''')
def connection_close(self):
self.connection.close()
def search_user(self, id, account_number):
self.cursor.execute('SELECT password, balance FROM Users WHERE (id, account_number) = (?, ?)', (id, account_number))
data = self.cursor.fetchone()
return data
def add_data(self, id, account_number, password, balance):
self.cursor.execute('INSERT INTO Users (id, account_number, password, balance) VALUES (?, ?, ?, ?)', (id, account_number, password, balance))
self.connection.commit()
def update_data(self, id, account_number, new_balance):
#print('database connect')
self.cursor.execute('UPDATE Users SET new_balance = ? WHERE (id, account_number) = (?, ?)', (new_balance, id, account_number))
self.connection.commit()
def delete_data(self, id, account_number):
self.cursor.execute('DELETE FROM Users WHERE (id, account_number) = (?, ?)', (id, account_number))
self.connection.commit()
def get_account_number(self):
self.cursor.execute('SELECT account_number FROM Users ORDER BY account_number DESC LIMIT 1')
data = self.cursor.fetchall()
#print(data)
if data == []:
return 0
else: return data[0][0] + 1
keyboards
from aiogram.types import (ReplyKeyboardMarkup, KeyboardButton,
InlineKeyboardMarkup, InlineKeyboardButton)
catalog_unknown = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text='Log in', callback_data='log_in'), InlineKeyboardButton(text='register', callback_data='register')]
])
catalog_logged = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text='Get account', callback_data='get_account'), InlineKeyboardButton(text='New account', callback_data='new_account')],
[InlineKeyboardButton(text='Close account', callback_data='close_account'), InlineKeyboardButton(text='Deposit', callback_data='deposit')],
[InlineKeyboardButton(text='Withdraw', callback_data='withdraw'), InlineKeyboardButton(text='Get balance', callback_data='get_balance')],
[InlineKeyboardButton(text='Show', callback_data='show')]
])
Также желаю получить мнение насчет практик, которые я использую. Буду рад, если скажете, как делать не надо, и как делать правильно. Принимаю любые советы по коду и спасибо всем, кто не полениться разобраться в той дичи, которую я понаписал