with one click
fastapi-endpoint
FastAPI 엔드포인트 보일러플레이트를 생성합니다. 라우터, 서비스, 스키마를 포함합니다.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
FastAPI 엔드포인트 보일러플레이트를 생성합니다. 라우터, 서비스, 스키마를 포함합니다.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
SQLAlchemy 2.0 쿼리, FastAPI 라우터/서비스 분리, Zustand 스토어, LangChain 에이전트 구현 패턴을 안내합니다. 백엔드 API 코드, 프론트엔드 상태관리, RAG 에이전트 작성 시 사용합니다.
pytest/Vitest 파일 구조, 커버리지 목표(75%+), fixture 패턴, RAGAS 평가 테스트를 안내합니다. 테스트 작성, 테스트 구조 설계, 커버리지 개선 시 사용합니다.
계획 파일을 읽고 즉시 코드를 구현합니다. 계획 모드 없이 파일별로 변경사항을 적용합니다.
Python 모듈의 pytest 테스트 스위트를 생성합니다. TDD 패턴을 따르는 테스트 코드를 작성합니다.
새 RAG 에이전트 클래스를 생성합니다. BaseAgent를 상속하고 벡터 컬렉션을 연결합니다.
React 컴포넌트와 테스트 코드를 생성합니다. TypeScript, TailwindCSS, Vitest를 사용합니다.
| name | fastapi-endpoint |
| description | FastAPI 엔드포인트 보일러플레이트를 생성합니다. 라우터, 서비스, 스키마를 포함합니다. |
새로운 FastAPI 모듈의 CRUD 엔드포인트를 생성합니다.
schedules)schedules)backend/apps/{module}/
├── __init__.py
├── router.py # API 엔드포인트
├── service.py # 비즈니스 로직
├── schemas.py # Pydantic 스키마
└── (models.py) # 필요시 별도 모델
AskUserQuestion으로 수집:
# apps/{module}/schemas.py
from datetime import datetime
from pydantic import BaseModel, Field, ConfigDict
class {Resource}Base(BaseModel):
"""기본 스키마"""
{field1}: {type1}
{field2}: {type2} | None = None
class {Resource}Create({Resource}Base):
"""생성 요청"""
pass
class {Resource}Update(BaseModel):
"""수정 요청 (모든 필드 Optional)"""
{field1}: {type1} | None = None
{field2}: {type2} | None = None
class {Resource}Response({Resource}Base):
"""응답"""
model_config = ConfigDict(from_attributes=True)
{primary_key}: int
created_at: datetime
updated_at: datetime | None = None
class {Resource}ListResponse(BaseModel):
"""목록 응답"""
items: list[{Resource}Response]
total: int
page: int = 1
size: int = 20
# apps/{module}/service.py
from sqlalchemy.orm import Session
from sqlalchemy import select, func
from apps.common.models import {Model}
from apps.{module}.schemas import {Resource}Create, {Resource}Update
class {Resource}Service:
def __init__(self, db: Session):
self.db = db
def get_by_id(self, {pk}: int) -> {Model} | None:
return self.db.get({Model}, {pk})
def get_list(
self,
page: int = 1,
size: int = 20,
**filters
) -> tuple[list[{Model}], int]:
"""페이지네이션 목록 조회"""
stmt = select({Model})
# 필터 적용
for key, value in filters.items():
if value is not None:
stmt = stmt.where(getattr({Model}, key) == value)
# 전체 개수
count_stmt = select(func.count()).select_from(stmt.subquery())
total = self.db.execute(count_stmt).scalar() or 0
# 페이지네이션
stmt = stmt.offset((page - 1) * size).limit(size)
items = list(self.db.execute(stmt).scalars())
return items, total
def create(self, data: {Resource}Create) -> {Model}:
item = {Model}(**data.model_dump())
self.db.add(item)
self.db.commit()
self.db.refresh(item)
return item
def update(self, {pk}: int, data: {Resource}Update) -> {Model} | None:
item = self.get_by_id({pk})
if not item:
return None
for key, value in data.model_dump(exclude_unset=True).items():
setattr(item, key, value)
self.db.commit()
self.db.refresh(item)
return item
def delete(self, {pk}: int) -> bool:
item = self.get_by_id({pk})
if not item:
return False
self.db.delete(item)
self.db.commit()
return True
# apps/{module}/router.py
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from apps.common.deps import get_db
from apps.auth.deps import get_current_user
from apps.{module}.service import {Resource}Service
from apps.{module}.schemas import (
{Resource}Create,
{Resource}Update,
{Resource}Response,
{Resource}ListResponse
)
router = APIRouter(prefix="/{resources}", tags=["{resources}"])
def get_service(db: Session = Depends(get_db)) -> {Resource}Service:
return {Resource}Service(db)
@router.get("/", response_model={Resource}ListResponse)
async def list_{resources}(
page: int = Query(1, ge=1),
size: int = Query(20, ge=1, le=100),
service: {Resource}Service = Depends(get_service),
current_user = Depends(get_current_user)
):
"""목록 조회"""
items, total = service.get_list(page=page, size=size)
return {Resource}ListResponse(
items=items,
total=total,
page=page,
size=size
)
@router.get("/{{pk}}", response_model={Resource}Response)
async def get_{resource}(
{pk}: int,
service: {Resource}Service = Depends(get_service),
current_user = Depends(get_current_user)
):
"""단일 조회"""
item = service.get_by_id({pk})
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="{resource}을(를) 찾을 수 없습니다"
)
return item
@router.post("/", response_model={Resource}Response, status_code=status.HTTP_201_CREATED)
async def create_{resource}(
data: {Resource}Create,
service: {Resource}Service = Depends(get_service),
current_user = Depends(get_current_user)
):
"""생성"""
return service.create(data)
@router.put("/{{pk}}", response_model={Resource}Response)
async def update_{resource}(
{pk}: int,
data: {Resource}Update,
service: {Resource}Service = Depends(get_service),
current_user = Depends(get_current_user)
):
"""수정"""
item = service.update({pk}, data)
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="{resource}을(를) 찾을 수 없습니다"
)
return item
@router.delete("/{{pk}}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_{resource}(
{pk}: int,
service: {Resource}Service = Depends(get_service),
current_user = Depends(get_current_user)
):
"""삭제"""
if not service.delete({pk}):
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="{resource}을(를) 찾을 수 없습니다"
)
# main.py에 추가
from apps.{module}.router import router as {module}_router
app.include_router({module}_router, prefix="/api/v1")
/pytest-suite 스킬 사용)/docs)| 항목 | 규칙 | 예시 |
|---|---|---|
| 모듈명 | snake_case (복수) | schedules |
| 클래스명 | PascalCase | ScheduleService |
| 엔드포인트 | kebab-case | /api/v1/schedules |
| 함수명 | snake_case | get_schedule |