API 키 관련 기능
API 키 추가
스키마 구현
from pydantic import BaseModel, Field
class UserInfo(BaseModel):
user_id: int = Field(..., alias="id")
user_name: str = Field(..., alias="name")
email: str
class AddNewAPIkeyRequest(BaseModel):
api_key : str
provider_id : int
provider_name : str
usage_limit : int
usage_count : int
class AddNewAPIkeyResponse(BaseModel):
message : str
요청으로 리액트에서 보내는 값들을 전부 받습니다.
그리고 응답으로 str 형태의 메세지를 전달하는 구조입니다.
UserInfo는 특정 요청에 대한 스키마가 아니라,
사용자 정보가 함께 입력될 때 범용적으로 사용할 수 있는 스키마입니다.
API 키 추가 기능에도 사용자 정보를 받기 위해 이 UserInfo를 사용합니다.
CRUD
def add_apikey(db: Session, api_key : str, provider_id : int, provider_name : str, usage_limit : int, usage_count:int, user_id:int):
new_apikey = ApiKey(
api_key = api_key,
provider_id = provider_id,
provider_name = provider_name,
usage_limit = usage_limit,
usage_count = usage_count,
user_id = user_id,
status = "Active"
)
db.add(new_apikey)
db.commit()
요청으로 입력된 데이터를 전부 DB 내의 테이블에 저장합니다.
status 값은 기본적으로 활성화 (Active) 상태로 설정합니다.
엔드포인트
@user_router.post("/AddNewAPIkey", response_model = AddNewAPIkeyResponse)
async def add_new_apikey(request: AddNewAPIkeyRequest, db : Session = Depends(get_db)):
api_key = request.api_key
provider_id = request.provider_id
provider_name = request.provider_name
usage_limit = request.usage_limit
usage_count = request.usage_count
user_id = request.user.user_id
try :
add_apikey(db=db, api_key=api_key, provider_id=provider_id, provider_name=provider_name,
usage_limit=usage_limit, usage_count=usage_count, user_id=user_id)
return JSONResponse(content={'message': 'API 키가 정상적으로 추가되었습니다.'}, status_code=200)
except Exception as e:
return JSONResponse(content={"message": f"오류 발생 : {str(e)}"}, status_code=500)
성공적으로 DB에 추가될 경우에는 성공적으로 추가되었다는 응답을 보내고,
그렇지 않을 경우에는 에러 코드를 반환합니다.
기타
사용자 DB 전화번호 추가
모델 코드 변경
class User(Base):
__tablename__ = "user_table"
id = Column(Integer, primary_key=True, autoincrement=True)
email = Column(String(255), unique=True, nullable=False)
password = Column(Text, nullable=False)
name = Column(String(100), nullable=False)
role = Column(String(50))
group = Column(String(100))
register_at = Column(TIMESTAMP, server_default=func.current_timestamp())
phone_number = Column(String(20), unique=True)
projects = relationship("Project", back_populates="user", lazy="dynamic")
전화번호를 phone_number라는 이름의 컬럼에 저장합니다.
중복 불가능한 값이기에 unique를 True로 설정했습니다.
010, 032같은 값들의 경우 int로 저장되면 앞자리의 0이 사라지기에 int가 아닌 str로 설정했습니다.
파일 업로드 에러
기존 문제

코드 수정
@langchain_router.post("/UploadFile", response_model=FileUploadResponse)
async def upload_file_endpoint(request: Request, db: Session = Depends(get_db)):
try:
form_data = await request.form()
project_id = form_data.get("project_id")
project_id = int(project_id) if project_id is not None else None
user_email = form_data.get("user_email")
session_id = form_data.get("session_id")
files = form_data.getlist("files[]")
save_dir = config.UPLOADED_FILES
os.makedirs(save_dir, exist_ok=True)
file_name, file_path = "", ""
for file in files:
file_name = file.filename
file_location = os.path.join(save_dir, file.filename)
with open(file_location, "wb") as f:
content = await file.read()
f.write(content)
file_path = f"{save_dir}/{file.filename}"
file_id = upload_file(db=db, project = project_id, email=user_email, url=file_path)
get_file_chain(db=db, id = file_id, file_path=file_path)
message1 = f"파일 업로드 : {file_name}"
message2 = "파일이 지식 베이스에 추가되었습니다. 어떤 도움이 필요하신가요?"
vector1 = text_to_vector(message1)
vector2 = text_to_vector(message2)
add_message(db = db, session_id = session_id, project_id = project_id, user_email=user_email, message_role='user', conversation=message1, vector_memory=vector1)
add_message(db=db, session_id = session_id, project_id = project_id, user_email=user_email, message_role='assistant', conversation=message2, vector_memory=vector2)
return JSONResponse(content={"message": "파일 업로드 성공"})
except Exception:
raise HTTPException(status_code=500, detail="파일 업로드 중 오류 발생")
함수명 중복으로 에러가 발생했던 것 같습니다.
현재 upload_file 함수 두 개 중 하나의 이름을 upload_file_endpoint로 변경해서 충돌을 피하도록 했습니다.