Application/Python

[Python] 28. 파이썬 졸업 프로젝트: 출근하면 책상에 보고서가 이미 와있는 시스템

devsalix 2026. 8. 28. 09:54
728x90

파이썬 졸업 프로젝트: 출근하면 책상에 보고서가 이미 와있는 시스템

아침에 회사 도착해서 컴퓨터 켜면, 메일함에 이런 게 하나 와있다고 상상해 보세요.

"오늘의 브리핑 - 파이썬 관련 뉴스 3건 요약, 원달러 환율 1,350원, 어제보다 5원 상승."

내가 잠자는 동안 누가 알아서 뉴스 뒤지고, 환율 확인하고, 중요한 것만 추려서 A4 한 장으로 정리해 책상에 올려둔 거예요. 매일 아침 뉴스 사이트 다섯 개 돌고, 환율 앱 켜고, 주식 창 확인하던 그 30분이 통째로 사라지는 거죠.

오늘 만들 게 바로 이거예요. 이름은 모닝 브리핑 봇.

그리고 미리 말씀드릴 게 하나 있어요. 이번 편은 새로운 걸 배우는 시간이 아니에요. 여기까지 오신 분이라면, 이 시스템을 만들 부품은 이미 다 갖고 계세요.


새 기술이 아니라 '조립'이에요

지금까지 편마다 하나씩 배운 것들 있잖아요. 뉴스 수집, 환율 가져오기, AI 요약, 메일 보내기, 슬랙 알림, 로그 남기기, 스케줄 걸기, 클라우드 올리기.

그게 전부 레고 블록이었어요. 우리는 그동안 블록을 하나씩 만들어 온 거예요.

이번 편은 그 블록들로 완성작을 조립하는 시간이에요. 성을 만들든 우주선을 만들든, 블록 자체는 이미 다 갖고 있잖아요. 새로 배울 개념은 거의 없어요. "어떤 순서로 이어 붙이느냐", 딱 그것만 하면 돼요.

솔직히 말하면 이 프로젝트에서 진짜 배우는 건 코드가 아니에요. 여러 개를 하나로 잇는 감각이에요. 그동안은 편마다 따로 실습했으니까, 여러 부품을 한 스크립트에서 이어 본 적이 없으셨을 거예요. 그 연결을 오늘 해보는 거죠.


어떤 부품이 어디서 왔을까

먼저 조립 지도를 펼쳐 볼게요. 이 봇은 이런 부품들로 이루어져요.

단계 하는 일 어디서 배웠나
수집 뉴스 검색 결과 가져오기 16편, 18편
수집 환율·주식 시세 가져오기 27편
요약 AI로 긴 내용 압축 21편, 22편
리포트 HTML 문서로 예쁘게 조립 07편, 14편
발송 메일·슬랙으로 전송 13편, 14편, 19편
안정성 로그 남기고 안 죽게 24편
자동 실행 매일 아침 정해진 시각에 23편
24시간 운영 내 PC 꺼도 돌아가게 26편

 

이 표 보시면 좀 안심되지 않으세요? 하나도 처음 보는 게 없잖아요. 전부 우리가 지나온 편들이에요.

여기서 중요한 건, 이걸 다 넣어야 하는 게 아니라는 점이에요. 뷔페지 풀코스가 아니에요. 아침에 주식 안 보시면 주식은 빼면 돼요. 뉴스랑 환율만 봐도 충분해요. 자기 아침 루틴에서 실제로 확인하는 것만 고르시면 됩니다.


전체 그림: 데이터가 한 방향으로 흐른다

이 시스템은 요리 코스랑 똑같아요.

재료 손질(수집) → 조리(요약) → 플레이팅(리포트 조립) → 서빙(발송).

앞 단계가 끝나야 다음이 시작되고, 각 단계는 앞에서 넘어온 걸 받아서 처리해요. 이런 걸 파이프라인(데이터가 한 방향으로 흐르는 처리 흐름)이라고 불러요. 말은 거창한데, 그냥 "손질한 재료를 냄비에 넣고, 조리한 걸 접시에 담는" 거예요.

이걸 코드로 옮기면 이렇게 돼요.

수집 → 요약 → 리포트 → 발송.

각 단계를 함수 하나로 만들어 두면, 전체가 레고처럼 딱딱 끼워져요.


핵심: main() 조립 골격

자, 이게 이 글의 하이라이트예요. 아래 골격만 이해하시면 절반은 끝난 거예요.

def collect():
    # 데이터를 모아서 하나로 묶어 돌려줍니다 (수집 단계)
    ...

def summarize(data):
    # 모은 데이터를 AI로 요약합니다 (요약 단계)
    return ai_summarize(data["news"])

def build_report(data, summary):
    # 요약 결과를 HTML 리포트로 조립합니다 (14편 방식)
    return f"<h1>오늘의 브리핑</h1>..."

def send(html):
    send_email(html)   # 메일로 보냅니다 (슬랙이면 send_slack)

def main():
    data = collect()                   # 1. 모으고
    summary = summarize(data)          # 2. 요약하고
    html = build_report(data, summary) # 3. 리포트 만들고
    send(html)                         # 4. 보낸다

if __name__ == "__main__":
    main()

 

main() 함수를 잘 보세요.

data = collect()로 받은 걸, summarize(data)에 넘기고, 그 결과를 다시 build_report에 넘겨요. 앞 함수가 돌려준 값을 다음 함수에 넘긴다, 이게 전부예요. 여러 부품을 잇는 비밀이 딱 이 한 줄이에요.

그리고 왜 함수로 나눴을까요? 한 덩어리로 위에서 아래로 쭉 써도 돌아가긴 해요. 그런데 나중에 "슬랙 말고 메일로 바꾸고 싶어" 할 때, 한 덩어리면 어디를 고쳐야 할지 막막해져요. 함수로 나눠두면 send() 하나만 손대면 끝나거든요. 레고 블록 하나만 갈아끼우는 거죠.


한 부품이 죽어도 전체는 살아남게

처음에 이 부분에서 많이 당황하시더라고요.

뉴스 사이트가 갑자기 응답이 없으면 collect()가 에러를 내고, 그 바람에 요약도 리포트도 발송도 다 멈춰버려요. 환율은 멀쩡히 가져왔는데도 아무것도 못 받는 거죠. 아침에 리포트를 기대하고 켰는데 텅 빈 상태, 좀 허무하잖아요.

그래서 각 수집 부품을 try/except로 따로따로 감싸줘요.

def collect():
    data = {}
    try:
        data["news"] = get_news("파이썬")  # 18편 검색 수집
    except Exception as e:
        log.error(f"뉴스 수집 실패: {e}")  # 24편 로깅
        data["news"] = []                  # 실패해도 빈 값으로 넘어감
    try:
        data["fx"] = get_exchange_rate()   # 27편 환율 수집
    except Exception as e:
        log.error(f"환율 수집 실패: {e}")
        data["fx"] = None
    return data

 

이렇게 해두면 뉴스가 터져도 환율은 살아서 넘어가요. "뉴스는 못 가져왔지만 환율은 정상"인 리포트가 도착하는 거죠. 반쪽짜리 리포트라도 아예 안 오는 것보단 훨씬 낫잖아요. 실패한 부품은 로그에 남으니까 나중에 왜 안 됐는지도 확인할 수 있고요. 24편에서 배운 로깅이 여기서 진가를 발휘해요.

한 가지만 더요. 이렇게 부품마다 따로 감싸두면, 나중에 새 부품을 붙일 때도 마음이 편해져요. 새로 추가한 게 말썽을 부려도 기존에 잘 돌던 것들까지 같이 무너지진 않으니까요.

전체가 완벽하게 도는 것보다, 한 곳이 터져도 나머지는 사는 게 훨씬 든든하거든요.


처음엔 아주 작게 시작하세요

혹시 지금 이런 생각 드시나요? "이 큰 걸 처음부터 다 만들어야 하나..."

절대 아니에요. 이게 가장 중요한 이야기예요.

이건 완성된 시스템이 아니라 자라나는 시스템이에요. 이렇게 키우시면 돼요.

  • v1: 뉴스 한 줄만 메일로 보내기 (이것만 돼도 성공이에요)
  • v2: 여기에 환율 추가
  • v3: AI 요약 붙이기
  • v4: 클라우드에 올려 매일 자동으로

하루에 블록 하나씩만 붙여도 일주일이면 꽤 그럴듯한 봇이 돼요. 처음부터 완벽하게 만들려고 하면 시작조차 못 해요. 뉴스 한 줄부터 가볍게 출발하세요.

그리고 v1이 딱 한 줄이라도, 그게 실제로 내 메일함에 도착하는 순간이 생각보다 짜릿하거든요. 그 작은 성공 한 번이 다음 블록을 붙일 힘을 줘요. 저도 그렇게 하나씩 늘려왔어요.


내 컴퓨터를 꺼도 매일 도착하게

여기까지 만들면 명령어를 칠 때마다 리포트가 오는 상태예요. 그런데 우리가 원하는 건 "내가 아무것도 안 해도" 매일 아침 오는 거잖아요.

그건 이미 배운 두 개를 연결하면 끝나요.

main.py를 23편 방식으로 매일 아침 7시에 돌게 스케줄을 걸고, 26편 방식으로 클라우드에 올리면 돼요. 그러면 내 컴퓨터를 꺼놔도, 심지어 자고 있어도, 매일 아침 리포트가 도착해요.

여기서 초보분들이 자주 걸리는 함정 두 개만 짚어 드릴게요.

하나, API 키를 코드에 그대로 박아두면 안 돼요. 클라우드에서 안 읽히기도 하고 유출 위험도 있어서, 26편에서 배운 환경변수로 빼두세요.

둘, 클라우드 서버는 보통 세계표준시(UTC)를 써요. 그래서 한국 아침 7시에 받으려면 서버 기준 시각을 그에 맞춰 설정해야 해요. 이거 놓치면 새벽 3시에 리포트가 와서 깜짝 놀라실 수 있어요.


여기서 더 키우고 싶다면

이 시스템의 진짜 매력은 부품 추가가 너무 쉽다는 것이에요.

날씨가 궁금하면 get_weather() 함수 하나 만들어서 collect()에 한 줄 추가하면 끝이에요. 구글 캘린더 일정, 팀 KPI 지표, 경쟁사 뉴스도 똑같은 방식으로 붙일 수 있어요. 발송도 메일이랑 슬랙 둘 다 보내거나, 개인용과 팀 공유용을 나눌 수도 있고요.

더 나아가면 브라우저에서 보는 웹 대시보드 형태로도 만들 수 있는데, 그건 Flask 같은 웹 도구가 필요해서 이 시리즈 밖의 다음 여정이에요.


여기까지 오신 당신에게

이제 진짜 마지막이네요.

먼저 이 말씀부터 드리고 싶어요. 여기까지 오신 것만으로 대단하신 거예요. 프로그래밍 시작한 사람의 대부분은 3편쯤에서 조용히 그만둬요. 끝까지 완주하는 사람은 정말 드물어요. 그런데 지금 이 글을 읽고 계시잖아요.

문법 몇 개 외운 게 중요한 게 아니에요. 진짜 달라진 건 따로 있어요.

이제 반복되는 업무를 마주치면, 아마 머릿속에 이런 생각이 먼저 떠오를 거예요. "이거... 자동화되나?"

그게 이 시리즈의 진짜 결과물이에요. 코드 몇 줄이 아니라 그 관점이요. 세상을 "손으로 할 일"과 "컴퓨터한테 시킬 일"로 나눠 보는 눈. 그건 한번 생기면 안 없어져요.

똑같은 엑셀을 매주 손으로 정리하다가 문득 "이거 지난주랑 똑같은데?" 싶은 순간, 예전 같으면 그냥 넘겼을 거예요. 근데 이제는 손이 먼저 멈추실 거예요. 그 멈칫하는 순간이 바로 달라진 증거예요.

그러니까 완벽하지 않아도 괜찮아요. 이 졸업 프로젝트도 뉴스 한 줄부터 시작하는 거잖아요. 작게 만들어서 내 것으로 조금씩 키우면 돼요.

다음 여정이 궁금하시다면, 더 큰 개인 프로젝트도 좋고, 웹개발이나 데이터 분석으로 넓혀 가도 좋아요. 그리고 이제는 만든 걸 동료와 나누거나 세상에 공개해 볼 차례이기도 해요. 혼자 배웠지만, 이제 나눌 수 있는 사람이 되셨으니까요.

다음 편은 없어요.

대신, 당신의 다음 프로젝트가 있죠.


 


제 글이 도움이 되셨다면 댓글 & 공감 부탁드려요 😀

 

 
728x90