간단한 Todo 리스트 API 구현
1. 프로젝트 설정
필요한 라이브러리 설치
pip install fastapi uvicorn
프로젝트 파일 구조
.
├── main.py
└── requirements.txt
2. FastAPI 서버 코드 작성
main.py
파일 내용
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List
app = FastAPI()
class Todo(BaseModel):
id: int
title: str
description: str = None
completed: bool = False
todos = []
@app.post("/todos/", response_model=Todo)
def create_todo(todo: Todo):
for t in todos:
if t.id == todo.id:
raise HTTPException(status_code=400, detail="Todo with this ID already exists")
todos.append(todo)
return todo
@app.get("/todos/", response_model=List[Todo])
def read_todos():
return todos
@app.delete("/todos/{todo_id}")
def delete_todo(todo_id: int):
for t in todos:
if t.id == todo_id:
todos.remove(t)
return {"message": "Todo deleted successfully"}
raise HTTPException(status_code=404, detail="Todo not found")
3. FastAPI 서버 실행
uvicorn main:app --reload
4. 발생한 문제와 해결 방법
문제 1: 404 Not Found
- 원인: 브라우저에서
http://127.0.0.1:8000
으로 접속하면 기본 경로("/")에 대한 처리가 없기 때문입니다. - 해결 방법: 기본 경로("/")에 HTML 파일을 제공하도록 설정.
문제 2: CORS (Cross-Origin Resource Sharing)
- 원인:
file:///
프로토콜을 사용하여 로컬 파일을 열 때 CORS 정책에 의해 교차 출원 요청이 차단됨. - 해결 방법: FastAPI 서버에 CORS 설정을 추가하여 CORS 문제 해결.
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"http://localhost",
"http://127.0.0.1:8000"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
문제 3: OPTIONS /todos/ HTTP/1.1 405 Method Not Allowed
- 원인: 브라우저가 CORS 프리플라이트 요청을 보내는데 서버에서 이를 처리하지 않아서 발생.
- 해결 방법: CORS 설정 추가로 해결.
문제 4: HTML 파일을 file:///
프로토콜로 열 때 CORS 문제
- 원인: 로컬 파일을 직접 열 때 CORS 정책에 의해 API 요청이 차단됨.
- 해결 방법: FastAPI 서버에서 HTML 파일을 제공하도록 설정.
@app.get("/", response_class=HTMLResponse)
def read_root():
with open("index.html") as f:
return HTMLResponse(content=f.read(), status_code=200)
5. HTML 파일 작성
index.html
파일 내용
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo List</title>
</head>
<body>
<h1>Todo List</h1>
<form id="todo-form">
<label for="id">ID:</label><br>
<input type="number" id="id" name="id" required><br>
<label for="title">Title:</label><br>
<input type="text" id="title" name="title" required><br>
<label for="description">Description:</label><br>
<input type="text" id="description" name="description"><br>
<label for="completed">Completed:</label><br>
<input type="checkbox" id="completed" name="completed"><br><br>
<input type="submit" value="Add Todo">
</form>
<script>
document.getElementById('todo-form').addEventListener('submit', async function(event) {
event.preventDefault();
const id = document.getElementById('id').value;
const title = document.getElementById('title').value;
const description = document.getElementById('description').value;
const completed = document.getElementById('completed').checked;
const todo = {
id: parseInt(id),
title: title,
description: description,
completed: completed
};
try {
const response = await fetch('http://127.0.0.1:8000/todos/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(todo)
});
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
console.log('Todo added:', data);
} catch (error) {
console.error('There was a problem with the fetch operation:', error);
}
});
</script>
</body>
</html>
6. 결과 확인
브라우저에서 http://127.0.0.1:8000
으로 접속하여 할 일을 추가하고, API가 제대로 작동하는지 확인합니다.
이와 같이 간단한 Todo 리스트 API를 FastAPI로 구현하고, 발생한 문제들을 해결하였습니다. 추가적인 문제가 발생하거나 다른 기능을 구현하고 싶다면 언제든지 말씀해 주세요! 다음 문제로 진행할 준비가 되시면 알려주세요.
'python_fastapi' 카테고리의 다른 글
[프로젝트]중기부 보도자료 크롤링 & MySql 저장 (0) | 2024.05.29 |
---|---|
강의 10: FastAPI 프로젝트 배포 (0) | 2024.05.28 |
강의 9: 사용자 인증 및 권한 부여 (0) | 2024.05.28 |
강의 8: 응답 모델 사용하기 (0) | 2024.05.28 |
강의 7: CRUD 작업 구현 (0) | 2024.05.28 |