chanwoo040531/lecture · 文件
文件最后提交记录最后更新时间
该仓库无文件或尚未加载
README.md
Todo API 과제
Python과 FastAPI를 사용해 Todo 관리용 REST API를 구현합니다. Todo의 생성, 조회, 수정, 삭제 기능은 필수이며, 데이터는 SQLite에 저장합니다.
필수 기술
- Python 3.12 이상
- FastAPI
- SQLite
- Git / GitHub
ORM, 패키지 관리 도구, 프로젝트 구조는 자유롭게 선택합니다.
구현 방향
Todo에는 제목과 완료 여부가 포함되어야 합니다. 설명, 마감일, 우선순위, 태그, 검색, 페이지네이션, 인증 등의 기능은 자유롭게 추가할 수 있습니다.
API 경로와 응답 형식은 직접 설계하며, 적절한 HTTP 메서드와 상태 코드를 사용합니다. 잘못된 입력과 존재하지 않는 데이터에 대한 처리도 구현합니다.
Claude Code를 포함한 AI 코딩 도구는 자유롭게 사용할 수 있습니다. 제출 시에는 코드의 구조와 동작을 설명할 수 있어야 합니다.
README에는 실행 방법, 사용 기술, API 목록, 구현한 기능을 작성하고, GitHub 저장소 형태로 제출합니다.
실행 방법
데이터는 Render Postgres(무료 플랜)에 저장합니다. 실행 전 환경변수를 설정해야 합니다.
DATABASE_URL— 앱이 접속할 Postgres 연결 문자열 (로컬 개발 시 Render 대시보드의 External Database URL을 사용)TEST_DATABASE_URL— 테스트 전용 접속 문자열. 운영 DB와 반드시 분리된 데이터베이스/스키마를 가리켜야 합니다 (테스트가 매번TRUNCATE를 실행하므로, 운영 DB를 가리키면 데이터가 삭제됩니다)
두 값 모두 실제 접속 자격증명을 포함하므로 이 저장소에는 커밋하지 않습니다 (.env 등 로컬 파일로 관리).
export DATABASE_URL="postgresql://..."
uv sync
uv run uvicorn app.main:app --reload
서버 실행 후 http://localhost:8000 에서 정적 UI를, http://localhost:8000/docs 에서 API 문서를 확인할 수 있습니다.
테스트 실행:
export TEST_DATABASE_URL="postgresql://..."
uv run pytest
Render 무료 플랜 관련 주의사항
- 무료 Postgres 인스턴스는 생성 후 30일이 지나면 만료/삭제됩니다. 학습/과제 목적 이상의 영구 운영에는 적합하지 않습니다.
- 무료 Web Service는 일정 시간 요청이 없으면 슬립 상태가 되며, 이후 첫 요청은 응답이 느릴 수 있습니다.
사용 기술
- Python 3.12+
- FastAPI, Uvicorn
- PostgreSQL (Render,
psycopg3, ORM 미사용) - bcrypt (비밀번호 해싱)
- uv (패키지 관리)
배포
Render Web Service(무료 플랜, Singapore 리전)로 배포되어 있습니다: https://todo-api-d7dr.onrender.com
API 엔드포인트
| Method | Path | 설명 | 인증 필요 |
|---|---|---|---|
| GET | /health | 헬스 체크 | X |
| POST | /todos | Todo 생성 | X |
| GET | /todos | Todo 목록 조회 | X |
| GET | /todos/{todo_id} | Todo 단건 조회 | X |
| PUT | /todos/{todo_id} | Todo 수정 | X |
| DELETE | /todos/{todo_id} | Todo 삭제 | X |
| POST | /signup | 회원가입 | X |
| POST | /login | 로그인, 세션 쿠키 발급 | X |
| POST | /logout | 로그아웃, 세션 무효화 | X |
| GET | /me | 현재 로그인한 사용자 조회 | O |
구현한 기능
- Todo CRUD (제목/설명/완료 여부, 생성·수정 시각 자동 관리)
- 이메일/비밀번호 기반 회원가입 (
bcrypt로 비밀번호 해싱, 이메일 중복 시 409) - 세션 기반 로그인/로그아웃 — 자체
sessions테이블에 토큰을 저장하고, 서명 없는 불투명 토큰을httponly쿠키로 발급하는 방식으로 구현 (StarletteSessionMiddleware/itsdangerous는 사용하지 않음) app/static/index.html에 로그인/회원가입/로그아웃을 위한 정적 UI 추가- 잘못된 입력(빈 제목, 짧은 비밀번호, 잘못된 이메일 형식 등)과 존재하지 않는 리소스에 대한 422/404/401/409 처리
설계 노트
- 이번 범위에서
/todos/*엔드포인트에는 로그인을 강제하지 않습니다. 인증이 필요하도록 확장하려면 각 라우터에Depends(get_current_user)를 추가하면 됩니다. - 로그인 쿠키는 로컬 HTTP 개발 환경 기준으로
secure=False로 설정되어 있습니다. HTTPS로 배포할 경우app/main.py의set_cookie호출에서secure=True로 변경해야 합니다.