
회사에서 업무 공유 문화를 개선하면서, 파이썬으로 노션 API, 슬랙 API를 활용해서 자동화를 했었다
간단하게 설명하자면, 트리거를 활용해 노션에서 오늘의 데일리 스크럼 페이지를 가져오고, 데이터를 정제해서 슬랙 메시지로 전송한다
[회고] 업무 효율성을 높일 때 필요한 것 (업무 공유 문화, 데일리 스크럼)
이전까지는 깃허브에도 안 올리고 (그러면 안되지만) 로컬 환경에서 그냥 코드 실행만 해왔다
그런데 이제 너무 많은 수정을 거쳤더니 버전 관리가 절실할 지경이 되었다
물론 다른 여러 이유들도 있지만, 모듈화하게 된 가장 큰 이유는 "깃허브에 올려 버전 관리를 하자!" 였다
기존 코드는 정말 지저분했다
물론 태초의 코드가 가장 지저분했지만,,,
처음에 일단 코드를 짜고, 그 다음 1차로 리팩토링한 상태로 유지해왔다
노션 API와 슬랙 API는 클래스화 해두었고, 기능 단위로 함수화해두긴 했지만 그럼에도 중복되는 코드가 보였고 개선할 부분이 눈에 보일 정도였다
처음에는 키파일만 분리해서 나머지 코드를 깃허브에 올리자!라는 생각이었다
그런데 파이썬에서 다른 파일을 참조하려면 모듈로 묶거나 환경 변수로 설정해야한다
환경 변수 보다는 모듈로 묶는 것이 깔끔할 것 같았고, 겸사겸사 다른 부분도 리팩토링하고자 모듈화로 방향을 잡았다
현재 프로젝트 구조는 다음과 같다
별도의 프레임워크를 사용한 것은 아니라서 똑같이 폴더 만들면 된다
my_project/
├── main.py # 메인 진입점
├── app/
│ ├── __init__.py # app 패키지 설정 파일
│ ├── services/ # API 서비스 관련 파일 폴더
│ │ ├── __init__.py
│ │ ├── notion_services.py # Notion API 관리 클래스
│ │ ├── slack_services.py # Slack API 관리 클래스
│ ├── modules/ # 메시징 등 비즈니스 로직 폴더
│ │ ├── __init__.py
│ │ ├── sendScrumModule.py # 스크럼 메시지 발송 모듈
└── config/
├── insert_keyfile_here.txt # 키파일 위치 알림 목적
└── keyfile.py # API 키 관리 파일
키파일에 넣을 값들 중에서 파이썬 딕셔너리가 몇 개 있었고, 굳이 이걸 .env 파일로 만들 필요성을 느끼지 못해서 keyfile.py 파일로 분리했다
테스트용으로 적어둔 키들도 주석으로 정리해서 넣어두었다
(슬랙으로 바로 메시지를 보내는거라, 실험용 채널로 보내지도록)
프로젝트 구조에 맞게 각 로직을 분리하고 공통되게 활용할 수 있는 건 함수로 묶었다
Notion API와 Slack API를 클래스로 선언해두긴 했지만, 확장성 따위 전혀 고려되지 않은 코드였는데, 이번에 수정하면서 확장성이 아주 좋아졌다고 자부한다
NotionRequest 클래스 인터페이스를 보면 이해하기 쉬울 듯 하다
기존 클래스
메인 파일 내 선언
class NotionRequest:
def __init__(self, token_key, today_date)
def get_daily_scrum(self)
def get_detail_task(self, condition, notion_id)
def get_upload_task(self, condition)
수정된 클래스
my_project/app/services/notion_services.py
class NotionRequest:
def __init__(self)
def getDatabase(self, database_id, condition)
def getPropsData(self, data, props_name, props_type)
함수명만 보더라도 종속성이 많이 사라졌고 확장성이 좋아졌다는 것을 파악할 수 있다
기존 클래스에서는 노션에서 데이터베이스 호출하는 작업부터 텍스트로 정제하는 것까지 모두 하나의 함수에서 작업했었다
이제는 클래스에서 공통 작업 (노션 API 호출 등)만 처리하고, 그 외 커스텀 작업 (텍스트 정제 등)은 메인 함수에서 처리하도록 분리했다
이 외에도 하나의 함수가 하나의 책임만을 가지도록 함수를 더 분리했다
함수 하나에 여러 작업이 물려있으면 나중에 수정하기 불편하고 가독성도 떨어진다
추후 로직을 추가하거나 수정할 때 용이하도록 함수 하나가 하나의 작업만을 수행할 수 있도록 하였다
(적고보니 SOLID 원칙이 떠오르는군,,,)
main.py에서 여러 모듈 중 일부만 선택해서 실행하고 싶었다
예를 들어, 스크럼 메시지 모듈과 주간 스프린트 모듈은 별개로 실행할 수 있어야 한다
Python에서는 다양한 방법을 사용할 수 있는데, 대표적으로 CLI(Command Line Interface) 에서 인자를 받아서 선택하는 방법이나, 메뉴 시스템을 이용하는 방법을 사용할 수 있다
본인은 추후 스크립트 자동화까지 노리고 있기에 CLI 인자를 사용하여 모듈을 선택하는 방법으로 적용했다
argparse 라이브러리를 사용해 명령줄 인자로 모듈을 선택할 수 있다
사용자는 실행할 모듈을 명령어로 지정하게 되고, 사용자가 지정하지 않은 명령어가 입력되는 경우 라이브러리 자체에서 예외 처리를 해준다고 한다
1. 라이브러리 및 모듈 import
import argparse
from app.modules.sendScrumModule import main_daily_scrum
from app.modules.sendSrpintModule import main_weekly_sprint
2. 각 모듈에 대한 함수 정의
def run_scrum_module():
main_daily_scrum()
def run_sprint_module():
main_weekly_sprint()
3. 딕셔너리로 모듈을 매핑
modules = {
"scrum": run_scrum_module,
"sprint": run_sprint_module
}
4. 명령줄 인자 설정
def main():
# 명령줄 인자 설정
parser = argparse.ArgumentParser(description="실행할 모듈을 선택하세요.")
parser.add_argument(
"module",
choices=modules.keys(),
help=f"실행할 모듈을 선택하세요: {', '.join(modules.keys())}"
)
# 명령줄 인자를 파싱
args = parser.parse_args()
# 선택된 모듈 실행
modules[args.module]()
5. 실행해보기
/my_project 경로에서 터미널로 실행하면 된다
python3 -B main.py scrum
-B는 __pycache__ 폴더 생성을 막는 옵션이므로 캐시 파일이 필요하다면 옵션 없이 실행하면 된다
사실 모듈화가 이렇게 재밌을 줄 몰랐다
단지 깃허브에 올려서 관리하기 위해 작업하게 된 건데, 이번 기회로 새로운 것에 눈을 뜬 것 같아서 아주 설렌다
회사에서 가끔 노션의 데이터를 일괄로 추출해서 활용할 때가 있는데, 그때마다 코드를 수정하는 게 은근 번거로웠다
그러나 이제는 이렇게 노션 데이터베이스를 참조하여 원하는 데이터를 정제해서 가져오는 작업을 더 간단하게 추가할 수 있다
앞으로 어떻게 이 코드를 활용할 수 있을지 너무 기대된다