파이콘 튜토리얼 reflex(구 pynecone) 강의를 듣고 나서.. (feat. 간단한 예제들)
오늘 파이콘 튜토리얼에 다녀왔습니다
저는 진짜 개발 1도 모름..
최근에 급하게 자바스크립트를 공부하긴 했지만 잘모르고.. 파이썬도 온전치 못한 코린이..
사실 개발할줄 아는 분이랑 같이 가려고 했는데 갑자기 일정 생기셔서 개발 아는분 없이 가게되었습니당..
튜토리얼 2개를 들었는데 모두 reflex (구 pynecone) 수업을 들었습니다
첫번째 수업은 진짜 1도 모르겠구.. 설치도 잘 안돼서 선생님께 너무 죄송함이..
그래도 reflex 특징에 대해서 알게된 시간이었습니다
간단히 정리한 내용을 적어보자면..
(+ 참고로.. 저에게 무언가를 물어보셔도 대답을 못할 가능성 101%.. 입니당.. ㅎㅎ 다른 멋진 개발자분들께 대답할 기회를 돌립니다...^^)
(++ node.js 설치를 필요로 합니다.)
Reflex 란?
- fast api, react, 기반 파이썬 풀 스택 웹 프레임워크
- 파이썬으로 컴포넌트를 작성하면 react(next.js) 컴포넌트로 변환되어 웹 브라우저에 표시
- chakra: chakra-ui 라이브러리를 래핑해서 기본적인 디자인, 컴포넌트가 내장되어 있음. 다른 라이브러리 래핑도 가능
- sql model, sqlalchemy 라이브러리를 래핑한 ORM 제공
- 수준이 높은 건 아님
- db 쪽은 실습에서 제외됨
- 장점:
- 빠르게 개발
- 리액트 몰라도 가능
- 리액트 컴포넌트 래핑해서 리액트 생태계 활용 가능
- 단점
- 기본적인 UI, CSS 지식 필요
- 웹소켓 기반으로 순수 REACT 보다 퍼포먼스 떨어짐
- 높은 활용을 위해선 원본 라이브러리 문서 참조 필요
- 특히 차크라 쪽
유사 프레임워크와의 비교
Django
- 목적성이 좀 다름
- 백엔드 서버라는 역할에 더 집중함
- 컴포넌트가 아닌 템플릿 엔진 기반이라, html css js 를 직접 작성 필요
ReactPy
- 동일하게 파이썬으로 컴포넌트 작성, 변환되어 웹 브라우저에 표시
- 좀 더 순수 React 에 가까움
Gradio
- ML/DL에 특화
- 함수 입출력을 web ui 로 래핑해주는 라이브러리
- 허깅페이스에서 쉽게 볼 수 있음
- rest api 기반
- 커스텀 요소가 적은편
그리고 두번째 수업도 reflex관련된걸 들었는데, 이 수업은 초급자를 위한 수업이여서 그런지 좀 코드 설명을 더 해주셔서 이해가 조금은? 되었습니다. (그럼에도 너무 몰라서 강사님이 저를 많이 신경써주셨습니다.. 감사합니다..)
집에 돌아와서 다시 한번 쭉 해보았는데 그 내용을 정리했습니다.
문제가 될 시 빛삭 예정입니다. (문제가 될만큼의 실력?이 아니여서 문제 없을듯 ^^)
목차
1. 설치 및 시작
새로운 프로젝트 폴더 생성 및 열기
터미널 cmd prompt 로 열기
가상환경 만들어주기
- 가상환경을 만드는 커맨드 하면 폴더에 가상환경 폴더가 생성됩니다.
python -m venv 가상환경이름
# 저의 경우 가상환경이름을 venv로 그대로 사용했습니다.
## 제 코드는 아래와 같음
python -m venv venv
가상환경 활성화
- 커맨드에 Scripts 폴더로 이동해준 뒤, activate.bat 입력
- 위치 앞에 가상환경 표시(venv) 가 되면 성공한 것
relfex 설치
설치 완료된 모습
reflex init
reflex run
localhost:3000
참고로 reflex docs는 아래 링크에서 확인 가능합니다.
https://reflex.dev/docs/getting-started/introduction/
Reflex | Docs
Reflex Docs Looking for Pynecone? You are in the right place, Pynecone is now Reflex! Reflex is an open-source, full-stack Python framework that makes it easy to build and deploy web apps in minutes. Motivation Reflex was created with the following goals:
reflex.dev
Scripts.py 를 메인 파일로 진행합니다.
2. 연습 예제
연습1) Hello World 출력
import reflex as rx
class State(rx.State):
pass
def index()->rx.Component:
return rx.heading("Hello world!")
app=rx.App()
app.add_page(index)
app.compile()
연습2) 컴포넌트 추가
docs 참고하여 추가
import reflex as rx
def index() -> rx.Component:
return rx.box(
rx.text("How are you?", text_align="right", margin_y="0.5em"),
rx.text("I'm fine. Thank you. And you?", text_align="left", margin_y="0.5em"),
rx.text("I'm fine, too. Thank you.", text_align="right", margin_y="0.5em"),
rx.text("Bye-bye!", text_align="left", margin_y="0.5em"),
rx.hstack(
rx.input(placeholder="질문을 남겨주세요."),
rx.button("제출"),
),
margin="10%")
app = rx.App()
app.add_page(index)
app.compile()
연습3) 스타일 적용하기
style.py생성해서 적용하기 (dictionary 로 생성)
style.py
shadow = "rgba(0, 0, 0, 0.15) 0px 2px 8px"
input_style = dict(
border_width="1px",
padding="1em",
box_shadow=shadow)
button_style = dict(
bg="#CEFFEE",
box_shadow=shadow)
Scripts.py (메인 파일)
간단히 style=~~로 적용 가능
import reflex as rx
from . import style # style.py import
def index() -> rx.Component:
return rx.box(
rx.text("How are you?", text_align="right", margin_y="0.5em"),
rx.text("I'm fine. Thank you. And you?", text_align="left", margin_y="0.5em"),
rx.text("I'm fine, too. Thank you.", text_align="right", margin_y="0.5em"),
rx.text("Bye-bye!", text_align="left", margin_y="0.5em"),
rx.hstack(
rx.input(placeholder="질문을 남겨주세요.", style=style.input_style),
rx.button("제출", style=style.button_style),
),
margin="10%")
app = rx.App()
app.add_page(index)
app.compile()
연습4) 숫자 카운터 만들기
State 사용
import reflex as rx
class State(rx.State):
num=0
def plus_one(self):
self.num +=1
def minus_one(self):
self.num -=1
def reset(self):
self.num =0
def index():
return rx.vstack(
rx.heading(State.num),
rx.hstack(
rx.button("-", on_click=State.minus_one),
rx.button("reset", on_click=State.reset),
rx.button("+", on_click=State.plus_one)
)
)
app=rx.App()
app.add_page(index)
app.compile()
3. ChatGPT 연동 채팅앱 만들기
- pip install openai
- ctrl +c 뒤로가기 후 pip install openai 입력
- 한번에 안될 수도 있는데, 몇 번 시도하면 됨..
- open ai key는 각자의 key값을 넣어주세요
다시 reflex run
저의 경우에는 윈도우여도 안떴는데, 에러가 나기도 한다고 합니다.
그럴 때에는 Kill or change? 라는 문구에서 kill을 해서 완전히 꺼주기를 하면 된다고 합니다.
Scripts.py (메인 파일)
import reflex as rx
from . import style
from .state import State
# qa 함수: 챗팅을 입력받은 뒤 각 챗팅을 질문, 박스 안에 개별 박스로 만들고,
# 답변에 따라 좌우 정렬
def qa(question: str, answer: str) -> rx.Component:
return rx.box(
rx.box(
rx.text(question, text_align="right"),
style=style.question_style,
),
rx.box(
rx.text(answer, text_align="left"),
style=style.answer_style,
),
margin_y="1em",
)
# state.py의 chat_history(배열)을 받아와서 qa함수에 입력
def chat() -> rx.Component:
return rx.box(rx.foreach(
State.chat_history,
lambda messages: qa(messages[0], messages[1]),
))
def action_bar() -> rx.Component:
return rx.hstack(
rx.input(id="question",
placeholder="Ask a question",
on_blur=State.set_question,
style=style.input_style,
),
rx.button("Ask",
on_click=State.answer,
style=style.button_style,
))
def index() -> rx.Component:
return rx.fragment(
rx.color_mode_button(rx.color_mode_icon(), float="right"),
rx.container(chat(), action_bar()))
app = rx.App()
app.add_page(index)
app.compile()
state.py
import reflex as rx
import os
import openai
openai.api_key = "입력"
class State(rx.State):
question: str
chat_history: list[tuple[str, str]]
def answer(self):
# Our chatbot has some brains now!
session = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": self.question}],
stop=None,
temperature=0.7,
stream=True)
answer = ""
self.chat_history.append((self.question, answer))
for item in session:
if hasattr(item.choices[0].delta, "content"):
answer += item.choices[0].delta.content
self.chat_history[-1] = (self.question, answer)
yield
style.py
import reflex as rx
shadow = "rgba(0, 0, 0, 0.15) 0px 2px 8px"
chat_margin = "20%"
message_style = dict(
padding="1em",
border_radius="5px",
margin_y="0.5em",
box_shadow=shadow,
color=rx.color_mode_cond(
light="rgb(107,99,246)",
dark="rgb(179, 175, 255)",
))
question_style = message_style | dict(
bg="#F5EFFE", margin_left=chat_margin)
answer_style = message_style | dict(
bg="#DEEAFD", margin_right=chat_margin)
input_style = dict(border_width="1px", padding="1em", box_shadow=shadow)
button_style = dict(bg="#CEFFEE", box_shadow=shadow, color="rgb(107,99,246)")
완성 모습
4. 배포
- 프론트엔드는 vercel을 통해 띄우는데, 백엔드는 안돼서 위와 같이 vs code에서 reflex run을 함
- 이 방법 외에도 방법이 있다고 함
- vercel.com 활용 (회원가입 필요)
vs에 vercel 설치
vercel 로그인
- .web으로 이동 후, vercel login 커맨드 실행
- 그럼 브라우저 창이 뜨고 로그인이 된다
vercel 실행
디폴트로 쭉 엔터치면 됨 (프로젝트 이름만 설정 필요)
vercel 완성
다시 reflex run
완성 모습