1분 안에 간단한 Python FastAPI ToDo 앱 개발

FastApi 앱



Completed App |
FastApi Official Website |

  • 프로젝트의 디렉토리를 만들고 탐색하십시오.

    mkdir fastapi-app && cd fastapi-app



  • Python 가상 환경 생성 및 활성화

    python3 -m venv venv
    ls
    source venv/bin/activate



  • Fastapi 설치

    pip install fastapi



  • ASGI 서버 설치

    pip install "uvicorn[standard]"



  • 템플릿용 패키지 설치

    pip install python-multipart jinja2



  • 데이터베이스 지원을 위한 패키지 설치

    pip install sqlalchemy


  • VSCode로 프로젝트를 열고 세 개의 파일 생성: app.py , database.pymodels.py

  • 메모:
    핍 업데이트python3 -m pip install --upgrade pip

    app.py




    from fastapi import FastAPI, Depends, Request, Form, status
    
    from starlette.responses import RedirectResponse
    from starlette.templating import Jinja2Templates
    
    from sqlalchemy.orm import Session
    from database import SessionLocal, engine
    import models
    
    models.Base.metadata.create_all(bind=engine)
    
    templates = Jinja2Templates(directory="templates")
    
    app = FastAPI()
    
    # Dependency
    def get_db():
        db = SessionLocal()
        try: 
            yield db
        finally:
            db.close()
    
    @app.get("/")
    async def home(req: Request, db: Session = Depends(get_db)):
        todos = db.query(models.Todo).all()
        return templates.TemplateResponse("base.html", { "request": req, "todo_list": todos })
    
    @app.post("/add")
    def add(req: Request, title: str = Form(...), db: Session = Depends(get_db)):
        new_todo = models.Todo(title=title)
        db.add(new_todo)
        db.commit()
        url = app.url_path_for("home")
        return RedirectResponse(url=url, status_code=status.HTTP_303_SEE_OTHER)
    
    @app.get("/update/{todo_id}")
    def add(req: Request, todo_id: int, db: Session = Depends(get_db)):
        todo = db.query(models.Todo).filter(models.Todo.id == todo_id).first()
        todo.complete = not todo.complete
        db.commit()
        url = app.url_path_for("home")
        return RedirectResponse(url=url, status_code=status.HTTP_303_SEE_OTHER)
    
    
    @app.get("/delete/{todo_id}")
    def add(req: Request, todo_id: int, db: Session = Depends(get_db)):
        todo = db.query(models.Todo).filter(models.Todo.id == todo_id).first()
        db.delete(todo)
        db.commit()
        url = app.url_path_for("home")
        return RedirectResponse(url=url, status_code=status.HTTP_303_SEE_OTHER)
    
    
    


    models.py




    from email.policy import default
    from sqlalchemy import Boolean, Column, Integer, String
    from database import Base
    
    class Todo(Base):
        __tablename__ = "todos"
    
        id = Column(Integer, primary_key=True)
        title = Column(String(100))
        complete = Column(Boolean, default=False) 
    
    


    데이터베이스.py




    import imp
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy.ext.declarative import declarative_base
    
    DB_URL = "sqlite:///./db.sqlite"
    
    engine = create_engine(DB_URL, connect_args = { "check_same_thread": False })
    
    SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
    
    Base = declarative_base() 
    
    


    템플릿/base.html




    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Todo App - Fastapi</title>
            <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.css">
            <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.js"></script>
        </head>
        <body>
            <div style="margin-top: 50px;" class="ui container">
                <h1 class="ui center aligned header">Fastapi ToDo App</h1>
    
                <form class="ui form" action="/add" method="post">
                    <div class="field">
                        <label>Todo Title</label>
                        <input type="text" name="title" placeholder="Enter ToDo task...">
                        <br>
                    </div>
                    <button class="ui blue button" type="submit">Add</button>
                </form>
    
                <hr>
    
                {% for todo in todo_list %} 
                <div class="ui segment">
                    <p class="ui big header">{{ todo.id }} | {{ todo.title }}</p>
    
                    {% if todo.complete == False %}
                    <span class="ui gray label">Not Complete</span>
                    {% else %}
                    <span class="ui green label">Complete</span>
                    {% endif %}
    
                    <a class="ui blue button" href="/update/{{ todo.id }}">Update</a>
                    <a class="ui red button" href="/delete/{{ todo.id }}">Delete</a>
    
                </div>
                {% endfor %}
    
            </div>
    
    
        </body>
    
    </html>
    
    



  • file_name:app_instance를 사용하여 uvicorn으로 앱을 실행하려면

    uvicorn app:app --reload



  • 앱 미리보기http://127.0.0.1:8000/ 및 기본 제공API Documentation

  • 코드를 커밋하고 github.com에 푸시하고 가상 환경을 비활성화합니다.

    $ 비활성화
    $ 콘다 비활성화
  • 📚 Sam의 다른 블로그: | Hashnode.dev | Medium.com
  • Github
  • 좋은 웹페이지 즐겨찾기