Creative Code

Lunar-(16)ai chat(구글 Gemini api 키 이용) 본문

Projects

Lunar-(16)ai chat(구글 Gemini api 키 이용)

빛하루 2024. 1. 21. 22:14


 

pages/aichat.py

 
전에 했던 aurora 에서 카카오 api 의 kogpt를 사용했더니 답변이 조금 부족해 Chat GPT나 google Bard를 사용하려고 시도했는데 두가지 방법다 오류?가나서 뜻밖의 최신ai버전인 구글 Gemini api를 사용하게 되었다. 답변의 정확성이 조금 올라간것 같은느낌도.. 우선 대화내용을 입력하면 답변이 데이터베이스에 저장되고  데이터베이스에 저장된 대화내역들을 전체 삭제할 수 있다.
 
내일은 날짜별로 대화내역저장 기능 + 디자인 수정 진행!
 
※pages/aichat.py 전체코드

# lunar.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from lunar.state.base import State
from lunar.state.home import HomeState

# 컴포넌트를 가져옵니다.
from ..components import container

color = "rgb(107,99,246)"
# 탭 버튼을 생성하는 함수
def tab_button(imagepath, href):
    """A tab switcher button."""
    return rx.link(
        rx.image(
            src=imagepath,
            height='40px',
            width='40px',
        ),
        display="inline-flex",
        align_items="center",
        py=3,
        px=2,
        href=href,  # 버튼 클릭 시 이동할 경로
    )

# 왼쪽에 표시되는 탭 스위처
def tabs():
    """The tab switcher displayed on the left."""
    return rx.box(
        rx.container(
            rx.hstack(
                rx.image(
                    src='/moon.png',
                    height='60px',
                    width='60px',         
                ),
                rx.text(
                    "Lunar", 
                    style={
                        "fontSize": "40px",
                        "fontWeight": "bolder",
                        "fontFamily": "Calibri, Calibri",
                        "background": "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
                        "-webkit-background-clip": "text",
                        "color": "transparent",
                    },
                    center_content=True,
                ),  # 앱 이름
            ),
        ),
        rx.container(height='30px'),
        py=4,
        overflow = 'auto',
    )

def gpt(gpt):
    box_color = rx.cond(gpt.author == "Gemini", "#99bed1", "#e2eb3b")
    return rx.vstack(
        rx.box(
            rx.hstack(
                rx.hstack(
                    rx.container(width='2px'),
                    rx.avatar(name=gpt.author, size="sm"), 
                ),
                rx.box(
                    rx.hstack(
                        rx.text("@" + gpt.author, font_weight="bold"),
                        rx.text("["+ gpt.created_at +"]"),  
                    ),
                    rx.text(gpt.content, width="auto"),  
                    width = 'auto',
                ),
                py=4,
                gap=1,
                width='auto',
            ),
            align_items='start',
            width = '97%',
            margin_left='5px',
            border_radius='20px',
            background=box_color,
        ),
        rx.container(height='5px'),
        margin_left='10px',
        align_items='start',
        width='auto',
    )
                
def feed_header(HomeState):
    return rx.hstack(
        rx.input(on_change=HomeState.set_user_input_chat, placeholder="Enter chat.."), 
        rx.button(
            "Enter",
            on_click = HomeState.chatai,
            border_radius="1em",
            box_shadow="rgba(151, 65, 252, 0.8) 0 15px 30px -10px",
            background_image="linear-gradient(144deg,#AF40FF,#5B42F3 50%,#00DDEB)",
            box_sizing="border-box",
            color="white",
            opacity="0.6",
            _hover={"opacity": 1},
        ),
        rx.button(
            "Clear",
            on_click = HomeState.clear_gpt,
            border_radius="1em",
            box_shadow="rgba(151, 65, 252, 0.8) 0 15px 30px -10px",
            background_image="linear-gradient(144deg,#AF40FF,#5B42F3 50%,#00DDEB)",
            box_sizing="border-box",
            color="white",
            opacity="0.6",
            _hover={"opacity": 1},
        ),
        justify="space-between",
        p=4,
        border_bottom="3px solid #ededed",
    )

# 피드 영역
def feed(HomeState):
    return rx.box(
        rx.container(height='10px'),
        feed_header(HomeState),
        rx.cond(
            HomeState.aichatting,
            rx.foreach(
                HomeState.aichatting,
                gpt
            ),
        ),
        border_x="3px solid #ededed",
        h="100%",
        overflow='auto'
    )

# 홈 페이지
def aichat():
    State.check_login
    return rx.vstack(
        rx.grid(
            tabs(),
            feed(HomeState),
            grid_template_columns="2fr 7fr",

            width='97%',
            h="90vh",
            gap=4,
        ),
        rx.grid(
            rx.vstack(
                rx.container(height='5px'),
                rx.button(
                    rx.icon(tag="moon"),
                    on_click=rx.toggle_color_mode,
                    width = '80%',
                    _hover={"bg": "orange.400"},
                ),
                width = '100%',
            ),
            rx.vstack(
                rx.hstack(
                    tab_button('/Home.png','/'),
                    tab_button('/profile.png','/profile'),
                    tab_button('/map.png','/map'),
                    tab_button('/chat.png','/chat'),
                    tab_button('/Aichat.png','/aichat'),
                    tab_button('/diary.png','/diary'),
                    tab_button('/video.png','/video'),
                    tab_button('/game.png','/game'),
                    tab_button('/music.png','/music'),
                    tab_button('/weather.png','/weather'),
                    tab_button('/setting.png','/setting'),
                    margin_right='5px',
                    border="1px solid #000000",
                    border_radius="full",
                    box_Shadow = '10px 10px 5px #3083f0',
                ),
                width = '100%',
            ),
            rx.vstack(
                rx.container(height='5px'),
                rx.button(
                    "Sign out",
                    on_click=State.logout,
                    bg="#212963",
                    color="white",
                    _hover={"bg": "blue.600"},
                    width = '80%',
                ),
                width = '100%',
            ),
            width='97%',
            grid_template_columns="2fr 5fr 2fr",
        ),
    )

 
※ state/home.py의 aichat부분 함수

# Gemini기능
    def chatai(self):
        if not self.logged_in:                                                            # 로그인되어 있지 않은 경우 알림
            return rx.window_alert("Please log in first")
        with open('googlegeminiapikey.json','r')as f:                                               
            key = json.load(f)
        googlegeminiapikey = key['key']
        genai.configure(api_key=googlegeminiapikey)
        model = genai.GenerativeModel('gemini-pro')
        gpt_response = model.generate_content(self.user_input_chat)
        with rx.session() as session:                                                     # 대화 내용을 데이터베이스에 저장
            gpt = GPT(
                author=self.user.username,
                content=self.user_input_chat,
                created_at=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            )
            session.add(gpt)
            session.commit()
            self.user_input_chat= ""

        with rx.session() as session:                                                     # KoGPT의 응답을 데이터베이스에 저장
            gpt = GPT(
                author = 'Gemini',
                content=gpt_response.text,
                created_at=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            )
            session.add(gpt)
            session.commit()
            
        return self.get_gpt() 
    
    # 데이터베이스에서 GPT 대화내역 가져오기
    def get_gpt(self):
        with rx.session() as session:
            self.aichatting = session.query(GPT).all()[::-1] 

    # chatgpt 대화내용 삭제
    def clear_gpt(self):
        self.aichatting = []
        with rx.session() as session:
            session.query(GPT).delete()
            session.commit()
        return self.get_gpt()

 
※state/base.py의 데이터베이스 GPT 모델링 부분
 

class GPT(rx.Model, table=True):
    content: str = Field() #유저의 질문내용, Gemini의 답변을 저장하는 영역
    author: str = Field() #질문 또는 답변의 작성자를 저장하는 영역
    created_at : str = Field() #질문 시각을 저장하는 영역