app이라는 folder 안에는 config.py, datanase.py, main.py, models.py 이렇게 4개의 .py파일로 구성되어져 있고, lib에는 telegram.py와 telegram api를 활용하기 위한 .env 파일로 구성되어져 있습니다.
우선 제가 사용한 환경의 requirements.txt입니다.
altair==5.2.0
annotated-types==0.6.0
anyio==3.7.1
attrs==23.2.0
bcrypt==4.1.2
blinker==1.7.0
cachetools==5.3.3
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==7.1.2
cryptography==3.4.7
defusedxml==0.7.1
ecdsa==0.18.0
exceptiongroup==1.2.0
fastapi==0.63.0
gitdb==4.0.11
GitPython==3.1.42
greenlet==3.0.3
h11==0.12.0
httpcore==0.13.7
httpie==3.2.2
httpx==0.18.1
idna==3.6
Jinja2==3.1.3
jsonschema==4.21.1
jsonschema-specifications==2023.12.1
markdown-it-py==3.0.0
MarkupSafe==2.1.5
mdurl==0.1.2
multidict==6.0.5
numpy==1.26.4
packaging==23.2
pandas==2.2.1
pillow==10.2.0
protobuf==4.25.3
pyarrow==15.0.2
pyasn1==0.5.1
pycparser==2.22
pydantic==1.10.15
pydantic_core==2.16.3
pydeck==0.8.1b0
Pygments==2.17.2
PyMySQL==1.1.0
PySocks==1.7.1
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
python-jose==3.3.0
python-multipart==0.0.9
pytz==2024.1
referencing==0.34.0
requests==2.31.0
requests-toolbelt==1.0.0
rfc3986==1.5.0
rich==13.7.1
rpds-py==0.18.0
rsa==4.9
six==1.16.0
smmap==5.0.1
sniffio==1.3.1
SQLAlchemy==2.0.29
starlette==0.13.6
streamlit==1.32.2
tenacity==8.2.3
toml==0.10.2
toolz==0.12.1
tornado==6.4
typing_extensions==4.10.0
tzdata==2024.1
urllib3==2.2.1
uvicorn==0.13.4
watchdog==4.0.0
database.py의 코드 내용은 다음과 같습니다. 자세한 내용은 https://kbgw2001.tistory.com/55과 비슷합니다.
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from app.config import settings
engine = create_engine(
"mysql+pymysql://{username}:{password}@{host}:{port}/{name}?charset=utf8mb4".format(
username=settings.DB_USERNAME,
password=settings.DB_PASSWORD.get_secret_value(),
host=settings.DB_HOST,
port=settings.DB_PORT,
name=settings.DB_NAME,
)
)
SessionLocal = sessionmaker(
bind = engine,
autocommit = False,
autoflush=False
)
Base = declarative_base()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
from functools import lru_cache
from pydantic import SecretStr
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
DB_USERNAME: str
DB_PASSWORD: SecretStr
DB_HOST: str
DB_PORT: int
DB_NAME: str #
TELEGRAM_BOT_TOKEN: SecretStr
class Config:
env_file = ".env"
env_file_encoding = "utf-8"
@lru_cache
def get_settings():
return Settings()
settings = get_settings()
class Config:
env_file = ".env"
env_file_encoding = "utf-8"
.env 파일의 설정 값입니다. 이렇게 env 파일을 만들어주면 알아서 자동적으로 .env에서 값들을 가져오게 됩니다.
여기서 DB_USERNAME과 DB_PASSWORD와 DB_PORT는 퀴즈봇 만들기 - 1에서 설정한 DB 내용들입니다.
docker로 설정한 DB가 꺼져있다면 다음 명령어로 실행 시켜주면 됩니다.
sudo docker start [container name]
ex) sudo docker start test-db
Settings을 바로 instance화 해주는 것이 아니라 함수를 통해서 instance화 하도록 하는 부분입니다.
@lru_cache
def get_settings():
return Settings()
settings = get_settings()
from sqlalchemy import Column, Integer, String
from app.database import Base
class User(Base):
__tablename__="user"
id = Column(Integer, primary_key=True)
email = Column(String, unique=True, index=True)
password = Column(String(255))
우선을 이렇게 User의 정보를 받도록 했습니다. main.py의 코드도 살펴 보겠습니다.
from fastapi import FastAPI
from
from app import models
from app.config import settings
from lib.telegram import Telegram
app = FastAPI()
telegram = Telegram(settings.TELEGRAM_BOT_TOKEN)
@app.on_event("startup")
def on_startup():
for app.database import engine
models.Base.metadata.create_all(bind = engine)
@app.get("/")
async def hello():
return b"hello world!"
@app.get("/me")
async def get_me():
return await telegram.get_bot_info()
여기서 우선 이 부분을 살펴 보겠습니다.
@app.on_event("startup")
def on_startup():
for app.database import engine
models.Base.metadata.create_all(bind = engine)
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
위의 main.py에 me라는 domain을 지정을 했습니다.
@app.get("/me")
async def get_me():
return await telegram.get_bot_info()
HTTPie를 사용해서 해당 부분에 대한 호출을 해보겠습니다.
http :8000/me
다음처럼 텔레그램에서 setting 했던 bot에 대한 내용들이 등장을 합니다.
lib 바로 아래 이렇게 telegram.py라는 파일이 있습니다.
from typing import Union
import httpx
from pydantic import SecretStr
class Telegram:
API_HOST = "https://api.telegram.org"
def __init__(self, token: Union[str, SecretStr]) -> None:
self._token = token
self.client = httpx.AsyncClient(base_url=self.host)
@property
def token(self):
if isinstance(self._token, SecretStr):
return self._token.get_secret_value()
return self._token
@property
def host(self):
return f"{self.API_HOST}/bot{self.token}/"
async def get_bot_info(self) -> dict:
"""Get current bot info"""
r = await self.client.get("getMe")
return r.json()
API_HOST = "https://api.telegram.org"
https://api.telegram.org/bot/METHOD_NAME
def __init__(self, token: Union[str, SecretStr]) -> None:
self._token = token
self.client = httpx.AsyncClient(base_url=self.host)
@property
def token(self):
if isinstance(self._token, SecretStr):
return self._token.get_secret_value()
return self._token
def __init__(self, token: Union[str, SecretStr]) -> None:
self._token = token
self.client = httpx.AsyncClient(base_url=self.host)
@property
def host(self):
return f"{self.API_HOST}/bot{self.token}/"
해당 부분이 아래 양식에 해당하는 부분입니다.
https://api.telegram.org/bot/METHOD_NAME
@app.get("/me")
async def get_me():
return await telegram.get_bot_info()
me라 path로 이동하게 되면, getMe라는 Method를 사용한 정보를 return하게 됩니다.
https://core.telegram.org/bots/api에서 검색을 해보면, 다음과 같이
봇에 대한 기본 정보를 반환하는 method라고 합니다. 위의 코드 통해서 편하게 실제 API의 method를 호출했다고 생각하면됩니다.
telegram bot을 만들고 간단하게 API를 호출해보고 test하는 코드를 작성해 보았습니다 !!
'FastAPI' 카테고리의 다른 글
퀴즈봇 만들기 - 2 (0) | 2024.04.07 |
---|---|
퀴즈봇 만들기 - 1 (0) | 2024.03.25 |
미들웨어 - 2 (0) | 2024.03.20 |
미들웨어 - 1 (0) | 2024.03.19 |
백그라운드 작업 - 2 (0) | 2024.03.13 |