question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Attribute error on updater

See original GitHub issue

For some reason I am getting an attribute error. Here is the stack: dependency-injector = “>=4.32.0”

Traceback (most recent call last):
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 398, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/fastapi/applications.py", line 199, in __call__
    await super().__call__(scope, receive, send)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/applications.py", line 111, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc from None
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/middleware/cors.py", line 78, in __call__
    await self.app(scope, receive, send)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/middleware/sessions.py", line 75, in __call__
    await self.app(scope, receive, send_wrapper)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc from None
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/routing.py", line 566, in __call__
    await route.handle(scope, receive, send)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/routing.py", line 227, in handle
    await self.app(scope, receive, send)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/starlette/routing.py", line 41, in app
    response = await func(request)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/fastapi/routing.py", line 201, in app
    raw_response = await run_endpoint_function(
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/fastapi/routing.py", line 148, in run_endpoint_function
    return await dependant.call(**values)
  File "/root/.local/share/virtualenvs/bot-Z2emI11w/lib/python3.9/site-packages/dependency_injector/wiring.py", line 624, in _patched
    result = await fn(*args, **to_inject)
  File "/app/bot/endpoints/bot_endpoints.py", line 37, in bot_index
    bot_service.updater.dispatcher.process_update(
AttributeError: 'dependency_injector.providers.ThreadSafeSingleton' object has no attribute 'updater'

bot_service.py

from providers.token_service import TokenService
from containers.token_container import TokenContainer
from setup.config import get_settings
from schema.token_info import GenericTokenInfo
from telegram.ext import CommandHandler, MessageHandler, Filters
from telegram.ext.callbackcontext import CallbackContext
from telegram.update import Update
from telegram import ParseMode, Bot
from telegram.ext import Updater
from dependency_injector.wiring import inject, Provider
from schema.token_info import GenericTokenInfo, TokenInfo
from loguru import logger
from telegram.ext import Updater


class BotService:
    def __init__(self) -> None:
        bot = Bot(get_settings().telegram_bot_api_key)
        self.updater = Updater(bot=bot, workers=0)
        # self._process_handlers()
        self._generate_token_commands()
        if get_settings().debug:
            self.updater.start_polling()
            self.updater.idle()

    def set_webhook(self) -> bool:
        hooked = self.updater.bot.set_webhook(
            url=f"{get_settings().telegram_bot_webhook_url}/{get_settings().telegram_bot_api_key}",
        )
        return hooked

    def main_menu(self, update: Update, context: CallbackContext) -> None:
        update.message.reply_text("Here are a list of commands available for to you!")

    def tokens(self, update: Update, context: CallbackContext) -> None:
        update.message.reply_text(
            "GODZ tokens:\n\n\tGODZ - GodZilliqa DAO token.\n\n\tGDFI - GodZilliqa DeFi token."
        )

    def whitepaper(self, update: Update, context: CallbackContext) -> None:
        update.message.reply_text("Whitepaper can be found here:")

    def new_member(self, update: Update, context: CallbackContext) -> None:
        for member in update.message.new_chat_members:
            if not member.is_bot:
                update.message.reply_text("Welcome to GodZilliqa DeFi,")

    def unknown(self, update: Update, context: CallbackContext) -> None:
        context.bot.send_message(
            chat_id=update.effective_chat.id,
            text="Use /start to find a list of commands.",
        )

    @inject
    def _generate_token_commands(
        self,
        token_service: TokenService = Provider[TokenContainer.token_provider],
    ) -> None:
        logger.info(type(token_service))
        tokens = token_service.get_all_tokens()
        for token in tokens:
            price = token_service.get_token_info(token.symbol)
            self._register_token_command(token, price)

    def _register_token_command(
        self, token: GenericTokenInfo, price: TokenInfo
    ) -> None:
        token_website = (
            f"\n<a href='{token.website}'>Website</a>" if token.website else ""
        )
        token_whitepaper = (
            f"\n<a href='{token.whitepaper}'>Whitepaper</a>" if token.whitepaper else ""
        )
        token_address = (
            f"\n<a href='https://viewblock.io/zilliqa/address/{token.address_bech32}'>{token.symbol} contract on viewblock.io</a>"
            if token.address_bech32
            else ""
        )
        token_zilstream = f"\n<a href='https://zilstream.com/tokens/{token.symbol}'>View {token.symbol} on zilstream.com</a>"
        token_price = f"\n<b>{price.rate:.2f} ZIL - ${price.rate_usd:.2f}</b>"
        token_info = (
            f"<b>{token.name} ({token.symbol})\nScore: {token.viewblock_score}/100</b>"
        )

        self.updater.dispatcher.add_handler(
            CommandHandler(
                token.symbol.lower(),
                lambda update, context: update.message.reply_text(
                    f"{token_info}{token_price}{token_website}{token_whitepaper}{token_address}{token_zilstream}",
                    parse_mode=ParseMode.HTML,
                    disable_notification=True,
                    disable_web_page_preview=True,
                    allow_sending_without_reply=True,
                ),
            )
        )

    def _process_handlers(self) -> None:
        self.updater.dispatcher.add_handler(CommandHandler("menu", self.main_menu))
        self.updater.dispatcher.add_handler(CommandHandler("tokens", self.tokens))
        self.updater.dispatcher.add_handler(
            CommandHandler("whitepaper", self.whitepaper)
        )
        self.updater.dispatcher.add_handler(
            MessageHandler(Filters.status_update.new_chat_members, self.new_member)
        )
        self.updater.dispatcher.add_handler(
            MessageHandler(Filters.command, self.unknown)
        )

bot_container.py

from providers.bot_service import BotService
from dependency_injector.containers import DeclarativeContainer
from dependency_injector.providers import ThreadSafeSingleton


class BotContainer(DeclarativeContainer):
    bot_provider: BotService = ThreadSafeSingleton(BotService)

start_web.py

from containers.token_container import TokenContainer
from containers.bot_container import BotContainer
from providers import bot_service
from fastapi import FastAPI
from fastapi.responses import ORJSONResponse
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.sessions import SessionMiddleware
from endpoints.api_endpoints import api_router
from setup.config import get_settings
from loguru import logger
from endpoints import bot_endpoints


@logger.catch
def setup_app() -> FastAPI:
    settings = get_settings()
    token_container = TokenContainer()
    token_container.wire(modules=[bot_service])
    bot_container = BotContainer()
    bot_container.wire(modules=[bot_endpoints])
    app = FastAPI(
        debug=settings.debug,
        title=settings.project_name,
        openapi_url=f"{settings.api_v1_str}/openapi.json",
        default_response_class=ORJSONResponse,
    )
    app.token_container = token_container
    app.bot_container = bot_container

    app.include_router(api_router)
    app.add_middleware(SessionMiddleware, secret_key=settings.api_secret_key)
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

    @app.on_event("startup")
    async def startup() -> None:
        pass

    @app.on_event("shutdown")
    async def shutdown() -> None:
        pass

    return app

bot_endpoints.py

from providers.bot_service import BotService
from containers.bot_container import BotContainer
from fastapi import APIRouter
from dependency_injector.wiring import inject, Provider
from telegram import Update
from fastapi.requests import Request
from setup.config import get_settings
from fastapi.responses import ORJSONResponse
from fastapi import Depends

telegram_bot_router = APIRouter()


@telegram_bot_router.get(f"/{get_settings().telegram_bot_api_key}/setwebhook")
@inject
async def bot_webhook(
    bot_service: BotService = Depends(Provider[BotContainer.bot_provider]),
) -> ORJSONResponse:
    return ORJSONResponse({"hooked": bot_service.set_webhook()})


@telegram_bot_router.get(f"/{get_settings().telegram_bot_api_key}/webhookinfo")
@inject
async def bot_webhook_info(
    bot_service: BotService = Depends(Provider[BotContainer.bot_provider]),
) -> ORJSONResponse:
    return ORJSONResponse(bot_service.dispatcher.bot.get_webhook_info().to_dict())


@telegram_bot_router.post(f"/{get_settings().telegram_bot_api_key}")
@inject
async def bot_index(
    request: Request,
    bot_service: BotService = Depends(Provider[BotContainer.bot_provider]),
) -> ORJSONResponse:
    data = await request.json()
    bot_service.updater.dispatcher.process_update(
        Update.de_json(data, bot_service.updater.dispatcher.bot)
    )
    return ORJSONResponse({})

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
rmk135commented, Apr 26, 2021

Hi @sjosegarcia ,

This error occurs because you use Provider wiring marker. It injects provider, but not an instance provided by provider. To fix the problem use Provide marker:

    bot_service: BotService = Depends(Provide[BotContainer.bot_provider]),
0reactions
sjosegarciacommented, May 13, 2021

I got it working. I am closing the issue. I needed to add the config into the container.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Django error <model> object has no attribute 'update'
The reason for this error is that .get() returns an individual object and .update() only works on querysets, such as what would be...
Read more >
Attribute error with updater #3121 - tiangolo/fastapi - GitHub
So for some reason, I am getting an attribute error, but I do not understand why. Here is the stack trace and code:...
Read more >
Attribute Error: "StopMarketOrder" does not have "Update"?
Hi all. This is the error code message: Runtime Error: AttributeError : 'StopMarketOrder' object has no attribute 'Update' at OnData in main.py:line 119...
Read more >
An unexpected failure occurred. Out of memory [table_name]
Technical Article Details : Error: Attribute Update: An unexpected failure occurred. Out of memory [table_name]
Read more >
RFC 7606: Revised Error Handling for BGP UPDATE Messages
Finally, it revises the error handling procedures for a number of existing attributes. This document updates error handling for RFCs 1997, 4271, 4360,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found