[ Pynecone ] ChatGPT App 만들기 (Python)
Pynecone Gallery에 보면 시계, Chart, Todo List, GPT 등 많은 예제를 소개하고 있습니다. 그 중에서 Chat completion API를 이용하여 이미지를 생성 App을 만들어 보겠습니다. (Example Code는 Github에서 확인 가능합니다.)
1. OpenAI API 키 발급
먼저 OpenAI API를 사용하기 위해 API 키 발급이 필요합니다. 먼저 OpenAI API 사이트로 이동합니다. OpenAI 계정이 필요하며 계정이 없다면 계정 생성이 필요합니다. 간단히 Google이나 Microsoft 계정을 연동 할 수 있습니다. 이미 계정이 있다면 로그인 후 진행하시면 됩니다.
로그인이 되었다면 우측 상단 Personal -> [ View API Keys ] 를 클릭합니다.
[ + Create new secret key ] 를 클릭하여 API Key를 생성합니다. API key generated 창이 활성화되면 Key 를 반드시 복사하여 두시기 바랍니다. 창을 닫으면 다시 확인할 수 없습니다. (만약 복사하지 못했다면 다시 Create new secret key 버튼을 눌러 생성하면 되니 걱정하지 않으셔도 됩니다.)
2. Installation
pip install --upgrade openai
3. Create a Project
dalle 라는 directory를 만들고 gpt.py 파일과 helpers.py 파일을 추가했습니다.
getting_started_with_pynecone
├── .web
├── assets
├── getting_started_with_pynecone
│ ├── __init__.py
│ └── getting_started_with_pynecone.py
├── gpt # 추가
│ ├── __init__.py # 추가
│ └── gpt.py # 추가
│ └── helpers.py # 추가
└── pcconfig.py
gpt.py 파일을 아래와 같이 수정합니다. openai.api_key 값은 위 OpenAI 에서 발급 받은 API KEY 값으로 입력합니다.
"""Welcome to Pynecone! This app is a demonstration of OpenAI's GPT."""
import pynecone as pc
from .helpers import navbar
import openai
import datetime
# OpenAI에서 발급 받은 API KEY를 입력
openai.api_key = "YOUR_API_KEY"
MAX_QUESTIONS = 10
class User(pc.Model, table=True):
"""A table for users in the database."""
username: str
password: str
class Question(pc.Model, table=True):
"""A table for questions and answers in the database."""
username: str
prompt: str
answer: str
timestamp: datetime.datetime = datetime.datetime.now()
class State(pc.State):
"""The app state."""
username: str = ""
password: str = ""
logged_in: bool = False
prompt: str = ""
result: str = ""
@pc.var
def questions(self) -> list[Question]:
"""Get the users saved questions and answers from the database."""
with pc.session() as session:
if self.logged_in:
qa = (
session.query(Question)
.where(Question.username == self.username)
.distinct(Question.prompt)
.order_by(Question.timestamp.desc())
.limit(MAX_QUESTIONS)
.all()
)
return [[q.prompt, q.answer] for q in qa]
else:
return []
def login(self):
with pc.session() as session:
user = session.query(User).where(User.username == self.username).first()
if (user and user.password == self.password) or self.username == "admin":
self.logged_in = True
return pc.redirect("/home")
else:
return pc.window_alert("Invalid username or password.")
def logout(self):
self.reset()
return pc.redirect("/")
def signup(self):
with pc.session() as session:
user = User(username=self.username, password=self.password)
session.add(user)
session.commit()
self.logged_in = True
return pc.redirect("/home")
def get_result(self):
if (
pc.session()
.query(Question)
.where(Question.username == self.username)
.where(Question.prompt == self.prompt)
.first()
or pc.session()
.query(Question)
.where(Question.username == self.username)
.where(
Question.timestamp
> datetime.datetime.now() - datetime.timedelta(days=1)
)
.count()
> MAX_QUESTIONS
):
return pc.window_alert(
"You have already asked this question or have asked too many questions in the past 24 hours."
)
try:
response = openai.Completion.create(
model="text-davinci-003",
prompt=self.prompt,
temperature=0,
max_tokens=100,
top_p=1,
)
self.result = response["choices"][0]["text"].replace("\n", "")
except:
return pc.window_alert("Error occured with OpenAI execution.")
def save_result(self):
with pc.session() as session:
answer = Question(
username=self.username, prompt=self.prompt, answer=self.result
)
session.add(answer)
session.commit()
def set_username(self, username):
self.username = username.strip()
def set_password(self, password):
self.password = password.strip()
def home():
return pc.center(
navbar(State),
pc.vstack(
pc.center(
pc.vstack(
pc.heading("Ask GPT", font_size="1.5em"),
pc.text_area(
default_value=State.result,
placeholder="GPT Result",
height="30em",
width="100%",
is_read_only=True,
),
pc.input(
on_blur=State.set_prompt, placeholder="Question",
),
pc.button("Get Answer", on_click=State.get_result),
# pc.button("Save Answer", on_click=State.save_result, width="100%"),
shadow="lg",
padding="1em",
border_radius="lg",
width="100%",
),
width="100%",
),
# pc.center(
# pc.vstack(
# pc.heading("Saved Q&A", font_size="1.5em"),
# pc.divider(),
# pc.data_table(
# data=State.questions,
# columns=["Question", "Answer"],
# pagination=True,
# search=True,
# sort=True,
# width="100%",
# ),
# shadow="lg",
# padding="1em",
# border_radius="lg",
# width="100%",
# ),
# width="100%",
# ),
width="50%",
spacing="2em",
),
padding_top="6em",
text_align="top",
position="relative",
)
def login():
return pc.center(
pc.vstack(
pc.input(on_blur=State.set_username, placeholder="Username", width="100%"),
pc.input(type_="password", on_blur=State.set_password, placeholder="Password", width="100%"),
pc.button("Login", on_click=State.login, width="100%"),
pc.link(pc.button("Sign Up", width="100%"), href="/signup", width="100%"),
),
shadow="lg",
padding="1em",
border_radius="lg",
background="white",
)
def signup():
return pc.box(
pc.vstack(
pc.center(
pc.vstack(
pc.heading("GPT Sign Up", font_size="1.5em"),
pc.input(
on_blur=State.set_username, placeholder="Username", width="100%"
),
pc.input(
type_="password", on_blur=State.set_password, placeholder="Password", width="100%"
),
pc.input(
type_="password",
on_blur=State.set_password,
placeholder="Confirm Password",
width="100%",
),
pc.button("Sign Up", on_click=State.signup, width="100%"),
),
shadow="lg",
padding="1em",
border_radius="lg",
background="white",
)
),
padding_top="10em",
text_align="top",
position="relative",
width="100%",
height="100vh",
background="radial-gradient(circle at 22% 11%,rgba(62, 180, 137,.20),hsla(0,0%,100%,0) 19%),radial-gradient(circle at 82% 25%,rgba(33,150,243,.18),hsla(0,0%,100%,0) 35%),radial-gradient(circle at 25% 61%,rgba(250, 128, 114, .28),hsla(0,0%,100%,0) 55%)",
)
def index():
return pc.box(
pc.vstack(
navbar(State),
login(),
),
padding_top="10em",
text_align="top",
position="relative",
width="100%",
height="100vh",
background="radial-gradient(circle at 22% 11%,rgba(62, 180, 137,.20),hsla(0,0%,100%,0) 19%),radial-gradient(circle at 82% 25%,rgba(33,150,243,.18),hsla(0,0%,100%,0) 35%),radial-gradient(circle at 25% 61%,rgba(250, 128, 114, .28),hsla(0,0%,100%,0) 55%)",
)
# Add state and page to the app.
app = pc.App(state=State)
app.add_page(index)
app.add_page(signup)
app.add_page(home)
app.compile()
helpers.py 파일은 아래와 같이 수정합니다.
import pynecone as pc
def navbar(State):
return pc.box(
pc.hstack(
pc.link(
pc.hstack(pc.image(src="favicon.ico"), pc.heading("Yunwoong GPT")), href="/"
),
pc.menu(
pc.menu_button(
pc.cond(
State.logged_in,
pc.avatar(name=State.username, size="md"),
pc.box(),
)
),
pc.menu_list(
pc.center(
pc.vstack(
pc.avatar(name=State.username, size="md"),
pc.text(State.username),
)
),
pc.menu_divider(),
pc.link(pc.menu_item("About GPT"), href="https://openai.com/api/"),
pc.link(pc.menu_item("Sign Out"), on_click=State.logout),
),
),
justify="space-between",
border_bottom="0.2em solid #F0F0F0",
padding_x="2em",
padding_y="1em",
bg="rgba(255,255,255, 0.90)",
),
position="fixed",
width="100%",
top="0px",
z_index="500",
)
4. Config
pcconfig.py의 app_name을 수정합니다.
import pynecone as pc
config = pc.Config(
app_name="gpt",
db_url="sqlite:///pynecone.db",
env=pc.Env.DEV,
)
5. Run the App
app을 실행해 보도록 하겠습니다. 브라우저 주소창에 http://localhost:3000를 입력 후 페이지 결과를 확인합니다.
$ pc run
'Tech & Development > AI' 카테고리의 다른 글
비정형 데이터 탐색: 벡터 임베딩과 벡터 데이터베이스의 이해 (0) | 2023.07.01 |
---|---|
PandasAI: 데이터 분석을 위한 대화형 AI 도구 (0) | 2023.05.25 |
[ Pynecone ] DALL·E 모델로 이미지를 생성 App 만들기 (Python) (0) | 2023.03.28 |
[ Python ] 미디어파이프(Mediapipe)를 이용한 가상 마우스 (4) | 2023.01.31 |
Fine tuning GPT3 Model (0) | 2023.01.04 |
댓글
이 글 공유하기
다른 글
-
비정형 데이터 탐색: 벡터 임베딩과 벡터 데이터베이스의 이해
비정형 데이터 탐색: 벡터 임베딩과 벡터 데이터베이스의 이해
2023.07.01 -
PandasAI: 데이터 분석을 위한 대화형 AI 도구
PandasAI: 데이터 분석을 위한 대화형 AI 도구
2023.05.25 -
[ Pynecone ] DALL·E 모델로 이미지를 생성 App 만들기 (Python)
[ Pynecone ] DALL·E 모델로 이미지를 생성 App 만들기 (Python)
2023.03.28 -
[ Python ] 미디어파이프(Mediapipe)를 이용한 가상 마우스
[ Python ] 미디어파이프(Mediapipe)를 이용한 가상 마우스
2023.01.31