depends() 함수를 정의하는 방법들
1. Pydantic 모델 사용
- 가장 일반적인 방법은 Pydantic 모델을 사용하여 의존성을 정의하는 것이다. 이 방법은 데이터 유효성 검사와 함께 데이터 변환을 처리할 수 있어 매우 편리하다.
from fastapi import Depends
from pydantic import BaseModel
class User(BaseModel):
username: str
password: str
def get_current_user(user: User = Depends()):
return user.username
# 사용 예제
@app.get("/users/me")
async def read_current_user(username: str = Depends(get_current_user)):
return {"username": username}
2. 함수 사용 - yield를 사용한 의존성
- 간단한 경우에는 함수를 직접 사용하여 의존성을 정의할 수 있습니다. 이 경우 함수의 반환값이 의존성으로 주입된다.
from fastapi import Depends
async def get_db():
db = SomeDatabase()
try:
yield db
finally:
db.close()
# 사용 예제
@app.get("/items/")
async def read_items(db: Database = Depends(get_db)):
return {"db_connection": db}
3. 직접 의존성 정의 - 일반적인 의존성 주입
- 필요에 따라 직접 의존성을 정의할 수도 있다. 이 경우 Depends()를 직접 호출하여 의존성을 제공할 함수를 전달한다.
from fastapi import Depends
async def get_current_user(token: str = Depends(get_token)):
user = await get_user_from_db(token)
return user
# 사용 예제
@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
return current_user
4. Annotated 사용
- 파라미터에 타입 어노테이션을 이용하여 의존성을 정의하는 방법이다.
from fastapi import Depends, FastAPI
app = FastAPI()
async def get_token():
token = "exampletoken"
return token
async def get_current_user(token: str = Depends(get_token)):
user = await fetch_user_from_token(token)
return user
@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
return current_user
5. 기본적인 클래스 의존성 주입
- 작동 방식
- get_service() 함수가 실행되어 Service 클래스의 인스턴스를 반환한다.
- Depends(get_service)를 통해 Service 인스턴스가 read_root 함수의 service 매개변수에 전달된다.
- read_root 엔드포인트에서 service.get_value()를 호출하여 응답을 반환한다.
from fastapi import FastAPI, Depends
app = FastAPI()
# 의존성으로 사용할 클래스
class Service:
def __init__(self):
self.value = "Hello, FastAPI!"
def get_value(self):
return self.value
# Depends를 사용하여 클래스 인스턴스를 주입
async def get_service():
return Service()
@app.get("/")
async def read_root(service: Service = Depends(get_service)):
return {"message": service.get_value()}
6. 싱글톤 패턴 적용 (한 번만 생성하여 사용)
- FastAPI는 기본적으로 요청이 들어올 때마다 새로운 의존성을 생성하지만, 싱글톤 패턴을 적용하면 애플리케이션이 실행되는 동안 하나의 인스턴스를 재사용할 수 있다.
- 작동 방식
- Service 인스턴스를 service_instance로 한 번만 생성하고 get_service()가 항상 같은 인스턴스를 반환하도록 한다.
- 모든 요청이 같은 Service 객체를 공유하여 싱글톤 방식으로 동작한다.
from fastapi import FastAPI, Depends
app = FastAPI()
# 싱글톤 인스턴스 생성
class Service:
def __init__(self):
self.value = "Singleton Instance"
def get_value(self):
return self.value
service_instance = Service() # 전역적으로 인스턴스를 한 번만 생성
async def get_service():
return service_instance # 항상 같은 인스턴스를 반환
@app.get("/")
async def read_root(service: Service = Depends(get_service)):
return {"message": service.get_value()}
7. 싱글톤 패턴 적용 - __call__을 활용한 클래스 의존성
- FastAPI에서는 클래스 자체를 Depends()로 사용할 수도 있다.
- 이를 위해 __call__ 메서드를 정의하면 된다.
- 작동 방식
- Depends(Service)는 Service()를 호출하여 인스턴스를 생성하고 주입한다.
- __call__이 정의되어 있기 때문에 Depends(Service)는 자동으로 Service의 인스턴스를 반환한다.
- 이 방식은 __call__을 정의한 클래스가 자동으로 인스턴스를 반환하도록 만들기 때문에, 별도의 get_service() 함수를 만들 필요가 없다.
from fastapi import FastAPI, Depends
app = FastAPI()
class Service:
def __init__(self):
self.value = "Service with __call__"
def __call__(self):
return self # 자기 자신을 반환
@app.get("/")
async def read_root(service: Service = Depends(Service)):
return {"message": service.value}
8. 옵션을 사용한 의존성 선언
- Depends()를 호출할 때 옵션을 추가하여 의존성을 선언할 수 있다. 예를 들어, 의존성의 이름을 지정하거나, 의존성을 캐싱하거나, 의존성의 범위를 제한하는 등의 설정을 추가할 수 있다.
from fastapi import Depends, FastAPI
app = FastAPI()
async def get_db():
db = SomeDatabase()
try:
yield db
finally:
db.close()
@app.get("/items/")
async def read_items(db: Database = Depends(get_db, use_cache=True)):
return {"db_connection": db}
9. 클래스 기반 의존성
- 의존성을 클래스 기반으로 정의하여 사용할 수도 있다. 이 방법은 의존성을 더욱 구조화하고 재사용성을 높일 수 있다.
- 일반적인 클래스를 의존성으로 주입하는 경우 __call__이나 __init__이 없어도 상관없다.
from fastapi import Depends, FastAPI
app = FastAPI()
class Database:
def __init__(self):
self.connection = None
def connect(self):
self.connection = "Connected"
def disconnect(self):
self.connection = None
def __call__(self):
if not self.connection:
self.connect()
return self
def get_db():
db = Database()
try:
yield db
finally:
db.disconnect()
@app.get("/items/")
async def read_items(db: Database = Depends(get_db)):
db_instance = db()
return {"db_connection": db_instance.connection}
'Study > fastapi' 카테고리의 다른 글
fastapi - G6 간단하게 훓어보기 - 2) API 호출 (0) | 2025.02.21 |
---|---|
fastapi - G6 간단하게 훓어보기 - 1) 설치 (0) | 2025.02.19 |
vscode, cusor ai에서 fastapi debug 하는 방법 with launch.json (0) | 2025.02.19 |
FastAPI에서 SQLAlchemy를 사용하여 테이블을 생성하는 방법 (0) | 2025.02.17 |
fastapi의 FastAPI() 메소드 사용법 정리 (0) | 2025.02.16 |
댓글