AttributeError: 'Updater' object has no attribute 'dispatcher'

반응형

안녕하세요?

 

텔레그램봇을 다시 설치하거나, 따라하기 하다보면, 잘 안되는경우가 있을 겁니다.

최근에  telegram.ext 라이브러리가 upgrade되면서 Updater 사용법이 많이 변경되었습니다.

 

구글링에서 가장 많은 예시 들이 존재하는 버젼이 python-telegram-bot-13.3 버젼입니다.

20.0버젼에 맞는 예시들이 아직은 거의 없는것 같습니다. 

 

python-telegram-bot-13.3 사용시에는 다음과 같이 사용합니다.

def start(update: Update, _: CallbackContext) -> None:
    user = update.effective_user
    update.message.reply_markdown_v2(
        fr'Hi {user.mention_markdown_v2()}\!',
        reply_markup=ForceReply(selective=True),
    )


def help_command(update: Update, _: CallbackContext) -> None:
    update.message.reply_text('Help!') 

def run_bot(update: Update, _: CallbackContext) -> None:
    replica = update.message.text
    answer = bot(replica)
    update.message.reply_text(answer) 

    print(replica)
    print(answer)
    print()
    
def main() -> None:
    updater = Updater("token")
    dispatcher = updater.dispatcher
    dispatcher.add_handler(CommandHandler("start", start))
    dispatcher.add_handler(CommandHandler("help", help_command))
    dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, run_bot))

    # Initialize bot
    updater.start_polling()

    updater.idle()

main()

 

python-telegram-bot-20.0 에서는 다음과 같이 사용합니다. 많이 틀리죠?

from telegram.ext import *
import keys
    
print('Starting a bot....')
     
async def start_commmand(update, context):
    await update.message.reply_text('Hello! Welcome To Store!')

if __name__ == '__main__':
    application = Application.builder().token(keys.token).build()

    # Commands
    application.add_handler(CommandHandler('start', start_commmand))

    # Run bot
    application.run_polling(1.0)

 

13.3 버젼을 사용하고 싶으시다면 제일 마직막에 13.3버젼으로 python-telegram-bot 을 다시 설치하시면 됩니다.

 

>pip install telegram
> pip uninstall python-telegram-bot telegram -y
>pip install python-telegram-bot
>pip install python-telegram-bot --upgrade
>pip install python-telegram-bot==13.3 # 20.0a0버젼부터는 dispatcher를 더이상 사용불가합니다. 

 

이상입니다.

 

https://stackoverflow.com/questions/74986002/attributeerror-updater-object-has-no-attribute-dispatcher

 

AttributeError: 'Updater' object has no attribute 'dispatcher'

When I run this code: from telegram.ext import * import keys print('Starting a bot....') def start_commmand(update, context): update.message.reply_text('Hello! Welcome To Store!') if

stackoverflow.com

 

반응형

댓글()

Python 3.7에서 torch install

반응형

구글링을 수십번 하면서, 3~4시간 헤메다가 찾은 방법입니다.

python 3.7에서 64bit OS환경이라면 하기 방법을 사용하시길 바랍니다.

>activate py37_64
>pip install torch===1.3.1 torchvision===0.4.2 -f https://download.pytorch.org/whl/torch_stable.html

반응형

댓글()

파이썬 개발을 도와주는 유용한 도구 IDE(Integrated Development Environment)

반응형
반응형

사실 파이썬 코딩에 사용할 수 있는 IDE는 정말 많습니다.

아래의 블로그에는 8가지 정도의 IDE를 간략히 소개했는데, 궁금하신 분들은 한 번 보시는 것도 좋을 것 같아요.

 

파이썬 IDE 사용 순위

그림 1 : 가장 인기있는 Python IDE, 2020 년 대비 사용량 점유율 2018

개인적으로 Pycharm을 활용하여 개발합니다만, 

cos pro등 pychon시험을 볼때는 jupyter나  google colab방식도 알려계시면 좋습니다. 

PyCharm: the Python IDE for Professional Developers by JetBrains

 

PyCharm: the Python IDE for Professional Developers by JetBrains

The Python & Django IDE with intelligent code completion, on-the-fly error checking, quick-fixes, and much more...

www.jetbrains.com

Project Jupyter | Home

 

Project Jupyter

The Jupyter Notebook is a web-based interactive computing platform. The notebook combines live code, equations, narrative text, visualizations, interactive dashboards and other media.

jupyter.org

Colaboratory에 오신 것을 환영합니다 - Colaboratory (google.com)

 

Google Colaboratory

 

colab.research.google.com

Wing Python IDE - Designed for Python (wingware.com)

 

Wing Python IDE - Designed for Python

Full-featured Python IDE with intelligent editor, powerful debugger, remote development error checking, refactoring, and much more. Wing was designed from the ground up for interactive Python development.

wingware.com

 

반응형

댓글()

파이썬 주석 단축키가 먹히지 않을때

반응형

https://dev-jinee.tistory.com/3

 

파이썬(python) 주석 단축키가 작동되지 않을 때

Windows 10 파이참 Pycharm 사용 시 주석 처리를 할 때의 단축키는 [ Ctrl + / ]이다. 간혹 위 단축키가 먹히지 않을 때가 있는데 그럴 때는 [ Ctrl + Shift ] 를 눌러 Microsoft 입력기로 바꿔주면 된다.

dev-jinee.tistory.com

여기서 답을 찾았네요. 감사합니다.

반응형

댓글()

asyncio로 비동기 처리하여 병렬처리 속도 높이기

반응형

파이썬은 기본적으로 동기 방식으로 동작하는 언어이지만, 파이썬 3.4에서 asyncio가 표준 라이브러리로 추가되고,

파이썬 3.5에서부터는 async/await 키워드가 문법으로 채택이 되면서, 파이썬도 이제 언어 자체적으로 비동기 프로그래밍이 가능해 졌다.

 

예를 들어, 다음과 같이 선언된 함수는 동기 함수입니다.

def do_sync(): 
     pass

기존 def 키워드 앞에 async 키워드까지 붙이면 이 함수는 비동기 처리되며, 이러한 비동기 함수를 파이썬에서는 코루틴(coroutine)이라고도 부릅니다.

async def do_async(): 
      pass

이러한 비동기 함수는 일반 동기 함수가 호출하듯이 호출하면 coroutine 객체가 리턴됩니다.

do_async() # <coroutine object do_async at 0x1038de710>

따라서 비동기 함수는 일반적으로 async로 선언된 다른 비동기 함수 내에서 await 키워드를 붙여서 호출해야 합니다.

async def main_async(): 
     await do_async()

async로 선언되지 않은 일반 동기 함수 내에서 비동기 함수를 호출하려면 asyncio 라이브러리의 이벤트 루프를 이용해야합니다.

loop = asyncio.get_event_loop() 
loop.run_until_complete(main_async()) 
loop.close()

파이썬 3.7 이상에서는 다음과 같이 한 줄로 간단히 비동기 함수를 호출 할 수도 있습니다.

asyncio.run(main_async())

 

실제 저의 프로그램에 구현하기(goldstock 프로그램 일부 발췌)

import asyncio

class Kiwoom(QAxWidget):
     def __init__(self):
          super().__init__()
          self.ui = SetupUI()
          self.realType = RealType()

          self.logging = Logging()
          self.slack = Slack() # 슬랙 동작

          #중간생략...

    def auto_AI_recommend_clicked(self):
          now = datetime.now()
          if self.ui.btnCdtResult_buy.isChecked():
               self.ai_recommend_timer_start()
          else:
               self.timer_ai_recommend.stop()
          return


     def ai_recommend_timer_start(self):
          self.timer_ai_recommend = QTimer()
          self.timer_ai_recommend.start(5 * 1000) # 5초 간격으로 
          self.timer_ai_recommend.timeout.connect(self.ai_recommend_click)

     def ai_recommend_click(self):

          market_status, decision_list = self.decide_to_autoTrading(stockCode)

          if market_status == "매수" or market_status == "강력매수":
               if self.ui.btnAutotrade.isChecked():
                    asyncio.run(self.decide_to_sell(1, stockCode))
                    asyncio.run(self.decide_to_sell(2, balance_detail_stockCode))

          else:
               if (market_status == "매도" or market_status == "강력매도") and stockCode in self.account_stock_dict:

                    if self.ui.btnAutotrade.isChecked():
                         asyncio.run(self.decide_to_sell(1, stockCode))
                         asyncio.run(self.decide_to_sell(2, balance_detail_stockCode))


     async def decide_to_sell(self, num, stockCode): 
          day_chart_data = {}
          minute_chart_data = {}
          week_chart_data = {}
          month_chart_data = {}
          recommInterval = str(self.ui.cbRecommInterval.currentText().replace(' ', ''))
          minute_chart_interval = str(self.ui.spinBox_minutes.value())


          market_status, decision_list = self.decide_to_autoTrading_condtion2(stockCode=stockCode)
          if market_status in ("매도", "강력매도"):
              self.time_to_trading(order_currency=stockCode, type="매도", market_status="매도", \
                    current_price=current_price, target_time=recommInterval, date=order_date, real_flag="R", \
                    decision_list=decision_list)

          elif market_status in ("매수", "강력매수"):
              self.time_to_trading(order_currency=stockCode, type="매수", market_status="매수", \
                    current_price=current_price, target_time=recommInterval, date=order_date, real_flag="R", \
                    decision_list=decision_list)

          else: # 관망
               pass
     def time_to_trading(self, order_currency="", type="", market_status="", target_units=0, current_price=0, \
               target_time="", date="", real_flag="", decision_list=""):
          if type in ("매도", "강력매도"): # 매도
               try:
                    self.sendOrder("신규매도", order_currency, "시장가", int(possible_quantity), int(current_price))
               except (ParameterTypeError, KiwoomProcessingError) as e:
                    self.showDialog('Critical', e)
                    return
               self.slack.notification(\
                    pretext="%s(%s) 시장가 매도주문 완료(로직No:%s)" % (stockName, order_currency, str_decision_list),
                    title="%s 주문수량: %s 현재가: %s" % (self.now.strftime("%Y-%m-%d %H:%M:%S"), possible_quantity, \
                            current_price),
                    text="https://finance.daum.net/chart/A%s" % order_currency)
          else:
               #매수주문
               try:
                    self.ui.pteLog.appendPlainText("%s(%s) (신규매수,시장가)주문전송" % (stockName, order_currency))
                    self.logging.logger.debug("%s(%s) (신규매수,시장가)주문전송" % (stockName, order_currency))
                    self.sendOrder("신규매수", order_currency, "시장가", int(target_units), int(current_price))
              except (ParameterTypeError, KiwoomProcessingError) as e:
                    self.showDialog('Critical', e)
                    self.ui.pteLog.appendPlainText("%s(%s) 매수주문 오류발생" % (stockName, order_currency))
                    self.logging.logger.debug("%s(%s) 매수주문 오류발생" % (stockName, order_currency))
                    return
          # 거래내역 DB저장
          self.insert_db_transaction_infos(self.not_account_stock_dict[self.orderNo]) # result

이 프로그램에 실제 구현하여 동시성 병렬프로그램 함수 처리속도가 배가 빨라졌습니다.

 

이 기능에 대한 설명은 하기 사이트를 참조하였습니다. 감사합니다.

https://www.daleseo.com/python-asyncio/

 

[파이썬] asyncio로 비동기 처리하기

Engineering Blog by Dale Seo

www.daleseo.com

 

반응형

댓글()

파이썬3 웹 크롤링 HTTP error 403 발생시 해결방법

반응형

안녕하세요?

 

오늘은 그동안 잘 되던 웹크롤링에서 http error 403 이 발생하여 해결한 내용 기록하겠습니다.

 

urllib . error . HTTPError :   HTTP  Error  403 :  Forbidden

 

에러가 발생한 이유는 mod_security 또는 다른 비슷한 서버 시큐리티가 알려진 사용자 봇을 블록 시키기 때문이라고 합니다.

가이드에 따라,

브라우저 유저 에이전트를 시도해 보았습니다.

 

수정전>

from urllib.request import Request, urlopen

urlTicker = urllib.request.urlopen('https://api.bithumb.com/public/ticker/%s_KRW' % ticker) 
readTicker = urlTicker.read()
jsonTicker = json.loads(readTicker)

<수정후>

from urllib.request import Request, urlopen

urlTicker = 
Request('https://api.bithumb.com/public/ticker/%s_KRW' % ticker, headers={'User-Agent': 'Mozilla/5.0'})
readTicker = urlopen(urlTicker).read()
jsonTicker = json.loads(readTicker)

오~ 역시, 깔끔하게 해결이 되었습니다.

 

다음 블러그를 참조하여 작성하였습니다. 도움에 감사드립니다.

 

m.blog.naver.com/PostView.nhn?blogId=naturelove87&logNo=221908009605&proxyReferer=https:%2F%2Fwww.google.com%2F

 

파이썬3 웹 크롤링 HTTP error 403이 뜰 때 해결하는 방법

파이썬3에서 urllib.request를 사용할 때 HTTP Error 403이 뜰 때 해결하는 방법​다음과 같은 코드를...

blog.naver.com

https://stackoverflow.com/questions/16627227/http-error-403-in-python-3-web-scraping

 

HTTP error 403 in Python 3 Web Scraping

I was trying to scrap a website for practice, but I kept on getting the HTTP Error 403 (does it think I'm a bot)? Here is my code: #import requests import urllib.request from bs4 import Beautiful...

stackoverflow.com

 

반응형

댓글()

ufunc 'add' did not contain a loop with signature matching types (dtype('<U170'), dtype('<U170')) -> dtype('<U170')

반응형

안녕하세요?

 

이 에러 메세지 원인을 못찾아서 거의 한시간을 헤멨습니다.

혹시, 이 에러 원인을 찾는 분이 계시다면 도움되시길 바랍니다.

 

다른 분들은 어떤 부분에서 에러나는지 모르겠지만,

저는 하기 sqlCode Text 문장을 만들어서 

 

try: 

    sqlCode = "select date, low from '" + ticker + "' t1 where t1.date <= (select max(t2.date) from '" + ticker + "' t2

    where t2.date < ( select date(max(t3.date), '-1 day') from '" + ticker + "' t3) and t2.low < " + current_price + ")"

 

    chart_data_low = pd.read_sql(sqlCode, con, index_col=None) # 추가로 인덱스 칼럼이 생성되지 않도록 한다.

except Exception as e:
    self.logging.logger.debug("(%s) retrieve_db_chart_data_low Exception발생: %s" % (ticker, e))
    print("chart_intervals: %s" % chart_intervals)

 

이렇게 하는 과정에서 Exception Error가 발생했습니다.

 

sqlCode 문자열을 생성할때, 문자열들만의 문자열 합하기가 되도록 중간중간의 인자값을 잘 확인하시기 바랍니다.

 

그럼, 즐(거운)파(이썬) 하시길 바랍니다.

반응형

댓글()

파이썬에서 Slack API를 통한 주식매매정보 보내기

반응형

안녕하세요?

 

오늘은 주식자동매매 구현시 자동매매 도중에 발생되는 정보나

Status, 추천종목정보, 자동매수 매도 결과를 자신의 Slack 메신저로 보내주기 위해

필요한 Slack API 설정 및 그 설정을 이용한 파이썬 코드, 

그리고, 그 결과 메세지가 전송된 결과 화면을 공유해 보고자 합니다.

 

1. slack API 설정화면

   하기 화면 메뉴에서 Bot User OAuth Access Token 값을 Copy합니다.

   여기서 token생성하는 과정은 다른 전문가님들의 가이드 메뉴 참조하시기 바랍니다.

   여기서는 생략하겠습니다. 

 

추가로, Scope도 추가 정의해 줘야 합니다.

slack bot에 access하는 application python에서 slack bot에 어떠어떠한 권한까지

가질수 있는지를 지정한다고 보시면 됩니다.

저는 channel읽기, chat에 글 올리기, 파일읽기 등 총 5가지 모두를 부여해 봤습니다.

 

2. Python slack.py 소스 코드

   우선 slack.py로 파이썬 코드를 분리했습니다.

   나중에 main 파이썬에서 from slack import *

   로 포함시키도록 하면 됩니다.

from slacker import Slacker

class Slack():
   def __init__(self):
       ############################################################
       # Slack API에서 "auto Traders" 
       # Installed App Settings
에서의 "OAuth Tokens for Your Team"
       #  >"Bot User OAuth Access Token"(Access Level: Workspace)
       ############################################################
       self.token = 'xoxb-1251878735248-1513295792086-k4wHoOdyjaWUsjXtVQL6JQeZ'

   def notification(self, pretext=None, title=None, fallback=None, text=None):
       attachments_dict = dict()
       attachments_dict['pretext'] = pretext
       attachments_dict['title'] = title
       attachments_dict['fallback'] = fallback
       attachments_dict['text'] = text

       attachments = [attachments_dict]

       slack = Slacker(self.token)
       slack.chat.post_message(channel='#gold-stock', text=None, attachments=attachments, as_user=None)

   Slack class내에 1번에서 copy한 token 값을 self.token에 저장하고,

   다른 class에서 notification 함수를 통해 호출할 수 있도록 정의합니다.

   

   다음은 main.py의 코드 일부입니다.

   매수 추천주를 골라서 slack으로 알려주는 기능입니다. 

from config.slack import *
...

class MyWindow(QWidget, metaclass=Singleton):
   def __init__(self, parent=None, **kwargs):
       super().__init__(parent, **kwargs)

      self.slack = Slack() # 슬랙 동작
   
  def ai_recommend_click(self):
      # 매수 추천주 확인
      market_status = self.get_recommend_items(stockCode, self.recommInterval, self.click_row)

      # 실제 매수 매도처리
      if market_status == "매수":
        self.slack.notification(pretext="(%s(%s)) 매수 추천종목" % (name, stockCode),
                                   t
itle="%s 자동매매 List에 추가했습니다. 로직No.(%s)" % (datetime.now().strftime("%Y-%m-%d %H:%M:%S"), str_decision_list),
                                   text="https://www.bithumb.com/trade/chart/" + stockCode + "_KRW")
      .
      .

 

이 부분이 slace에서 메세지로 받아보면 아래와 같은 메세지를 slack에서 자동으로 

받아볼 수 있습니다.

여기서 맨 마지막 URL Link를 누르면, 다음 화면으로 연결도 됩니다. ^^

 

이상으로 띄엄띄엄이긴 하지만, slack bot을 통해서

파이썬 자동매매 프로그램에서 종목을 추천한 결과를 slace 메세지로 보내고,

slack 에서 해당 메세지를 보고, 첨부된  url링크를 눌러서 

추가 상세정보도 확인할 수 있다는 걸 

간단한 예로 보여드렸습니다.

 

이상입니다.

반응형

댓글()