파이썬과 FastAPI를 사용하여 뉴스레터를 만드는 과정입니다.
- FastAPI 소개
- FastAPI는 빠르고 현대적인 웹 프레임워크로, 파이썬을 기반으로 하는 비동기 웹 어플리케이션을 쉽게 작성할 수 있도록 지원합니다.
- 프로젝트 설정
- FastAPI를 설치하고 새로운 프로젝트를 초기화합니다. 이때, Pydantic을 사용하여 데이터 모델을 정의합니다.
- 이메일 전송 설정
- 뉴스레터를 보낼 때 사용할 이메일 전송 서비스를 설정합니다. 보통은 SMTP 서버를 사용하는데, 이를 위해
smtplib
를 사용할 수 있습니다.
- 뉴스레터를 보낼 때 사용할 이메일 전송 서비스를 설정합니다. 보통은 SMTP 서버를 사용하는데, 이를 위해
- 데이터베이스 설정
- 사용자 정보와 뉴스레터 구독 정보를 저장하기 위해 데이터베이스를 설정합니다. 이때,
SQLAlchemy
나ORM
을 활용하여 데이터 모델을 정의하고 데이터베이스에 연결합니다.
- 사용자 정보와 뉴스레터 구독 정보를 저장하기 위해 데이터베이스를 설정합니다. 이때,
- API 엔드포인트 구현
- FastAPI를 사용하여 구독자 추가, 삭제, 뉴스레터 전송 등을 처리하는 API 엔드포인트를 구현합니다.
- 이메일 발송
- 이메일을 발송하는 부분에서는 SMTP 서버를 이용하여 사용자에게 뉴스레터를 전송합니다. 여기서는
smtplib
를 사용하여 이 작업을 처리합니다.
- 이메일을 발송하는 부분에서는 SMTP 서버를 이용하여 사용자에게 뉴스레터를 전송합니다. 여기서는
- 프로젝트 실행 및 테스트
- 프로젝트를 실행하고 API 엔드포인트를 테스트하여 정상적으로 동작하는지 확인합니다.
- 추가 기능 (선택 사항)
- 필요에 따라 구독자 관리 기능, 이메일 템플릿 설정, 예약 발송 기능 등을 추가로 구현할 수 있습니다.
Python과 FastAPI에 대한 기본적인 이해가 필요하며, Kindle에서 추출한 하이라이트를 저장하고, 주기적으로 하이라이트 중 하나를 이메일로 받아볼 수 있는 뉴스레터 서비스를 구축합니다. 아래는 프로젝트의 핵심 부분을 단계별로 설명한 것입니다.
FastAPI를 사용한 웹 앱 설정
- FastAPI는 빠르고 비동기 처리가 가능한 웹 애플리케이션 프레임워크입니다.
- 네 가지 간단한 엔드포인트를 가진 웹 앱을 만듭니다.
- 홈 페이지: 뉴스레터 가입 폼을 표시합니다.
- 사용자로부터 제출된 폼 데이터를 처리하는 엔드포인트.
- 뉴스레터 구독 확인을 위한 엔드포인트.
- 뉴스레터 구독 취소를 위한 엔드포인트.
비동기 처리 및 백그라운드 작업
- FastAPI의 비동기 및 백그라운드 작업을 활용하여 이메일 전송, 사용자 등록 및 하이라이트 업로드를 비동기적으로 처리합니다.
async
및background_tasks
를 사용한 예제 코드를 통해 이를 구현합니다.
데이터베이스 설정
- PynamoDB를 사용하여 DynamoDB와 상호 작용하는 모델을 정의합니다.
HighlightModel
은 Kindle에서 추출한 각 하이라이트의 데이터 모델을 나타냅니다.
AWS Elastic Beanstalk을 이용한 배포
- AWS Elastic Beanstalk를 사용하여 Docker 기반 애플리케이션을 배포합니다.
- GitHub Actions를 활용하여 자동 업데이트 및 배포를 구성합니다.
이메일 발송 설정
- Amazon SES를 사용하여 이메일을 전송합니다.
- 주기적인 작업으로 매주 금요일에 이메일을 전송하기 위해 GitHub Actions를 사용합니다.
send_email.py
스크립트를 사용하여 사용자에게 주간 하이라이트를 이메일로 보냅니다.
GitHub Actions를 통한 CI/CD 설정
- GitHub Actions를 사용하여 두 가지 중요한 작업을 자동화합니다.
- 매번 마스터 브랜치에 커밋이 발생하면 Elastic Beanstalk에 자동으로 애플리케이션을 업데이트하고 재배포합니다.
- 매주 금요일에
send_email.py
스크립트를 실행하여 뉴스레터를 사용자에게 자동으로 전송합니다.
마무리
- 전체 프로세스를 통해 새로운 기술들을 배우고, 뉴스레터 서비스를 직접 구축하는 경험을 통해 다양한 기술에 대한 존경을 얻었습니다.
- 최종 결과물은
Kindle-highlights.email
이라는 무료 오픈소스 프로젝트로, 사용자는 하이라이트 파일을 업로드하고 매주 금요일에 강조된 구절을 이메일로 받을 수 있습니다.
이제 프로젝트의 핵심 부분에서 사용된 코드를 추가하여 단계별로 자세하게 설명하겠습니다.
FastAPI를 사용한 웹 앱 설정
# main.py
from fastapi import FastAPI, BackgroundTasks, File, Form, Request, UploadFile
from fastapi.responses import FileResponse
from app.utils import (
parse_highlights_file,
email_is_valid,
check_user_subscribed,
register_user,
send_confirmation_to,
upload_highlights,
)
from fastapi.templating import Jinja2Templates
app = FastAPI()
templates = Jinja2Templates(directory="templates")
@app.post("/")
async def sign_up(
request: Request,
background_tasks: BackgroundTasks,
file: UploadFile = File(...),
email: str = Form(...),
):
highlights = await parse_highlights_file(file)
email_valid = await email_is_valid(email)
if not highlights or email_valid is False:
return FileResponse("static/error.html")
subscribed_status = await check_user_subscribed(email)
if subscribed_status is False:
background_tasks.add_task(register_user, email)
background_tasks.add_task(send_confirmation_to, email)
background_tasks.add_task(upload_highlights, highlights, email)
return templates.TemplateResponse("sign_up.html", {"request": request})
else:
return templates.TemplateResponse("success.html", {"request": request})
데이터베이스 설정
# models.py
from pynamodb.models import Model
from pynamodb.attributes import (
UnicodeAttribute,
UTCDateTimeAttribute,
BooleanAttribute,
NumberAttribute,
)
class HighlightModel(Model):
class Meta:
table_name = "kindle-highlights-contents"
region = "eu-west-1"
email = UnicodeAttribute(hash_key=True, null=False)
author = UnicodeAttribute(null=False)
book = UnicodeAttribute(null=False)
content = UnicodeAttribute(null=False)
date_string = UnicodeAttribute(null=False)
highlight_index = NumberAttribute(range_key=True, null=False)
AWS Elastic Beanstalk을 이용한 배포
- Dockerfile
# Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.8
COPY ./app /app
- docker-compose.yml
# docker-compose.yml
version: "3"
services:
app:
build:
context: .
dockerfile: Dockerfile
environment:
- MODULE_NAME=main
- VARIABLE_NAME=app
ports:
- "80:80"
depends_on:
- dynamodb
dynamodb:
image: amazon/dynamodb-local
ports:
- "8000:8000"
CI/CD: GitHub - (ab)using GitHub actions
- 업데이트 및 배포
# .github/workflows/deploy.yml
name: Deploy to AWS Elastic Beanstalk
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Deploy to Elastic Beanstalk
run: eb deploy
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- 주간 뉴스레터 발송
# .github/workflows/send_newsletter.yml
name: Send Weekly Newsletter
on:
schedule:
- cron: "0 8 * * 5" # Every Friday at 8 AM
jobs:
send_newsletter:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run send_email.py script
run: python app/send_email.py
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
이러한 코드와 설정을 통해 Kindle 하이라이트 뉴스레터 서비스를 개발하고, AWS Elastic Beanstalk 및 GitHub Actions를 사용하여 배포 및 자동화를 구현할 수 있습니다.
728x90
댓글