+ Pynecone์ ์ฐพ๊ณ ๊ณ์ ๊ฐ์? ์ด๊ณณ์ด ๋ง์ต๋๋ค. Pynecone์ ์ด์ Reflex๋ก ๋ถ๋ฆฝ๋๋ค. +
English | ็ฎไฝไธญๆ | ็น้ซไธญๆ | Tรผrkรงe | เคนเคฟเคเคฆเฅ | Portuguรชs (Brasil) | Italiano | ํ๊ตญ์ด
ํฐ๋ฏธ๋์ ์ด๊ณ ์คํํ์ธ์. (Python 3.8+ ํ์):
pip install reflex
reflex
๋ฅผ ์ค์นํ๋ฉด, reflex
๋ช
๋ น์ด ๋ผ์ธ ๋๊ตฌ๋ ์ค์น๋ฉ๋๋ค.
์ ํ๋ก์ ํธ๋ฅผ ์์ฑํ์ฌ ์ค์น๊ฐ ์ฑ๊ณต์ ์ธ์ง ํ์ธํฉ๋๋ค. (my_app_name
์ ํ๋ก์ ํธ ์ด๋ฆ์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค.):
mkdir my_app_name
cd my_app_name
reflex init
์ด ๋ช ๋ น์ด๋ ์ ๋๋ ํ ๋ฆฌ์ ํ ํ๋ฆฟ ์ฑ์ ์ด๊ธฐํํฉ๋๋ค.
๊ฐ๋ฐ ๋ชจ๋์์ ์ด ์ฑ์ ์คํํ ์ ์์ต๋๋ค:
reflex run
http://localhost:3000 ์์ ์ฑ์ด ์คํ ๋ฉ๋๋ค.
์ด์ my_app_name/my_app_name.py
์์ ์์ค์ฝ๋๋ฅผ ์์ ํ ์ ์์ต๋๋ค. Reflex๋ ๋น ๋ฅธ ์๋ก๊ณ ์นจ์ ์ง์ํ๋ฏ๋ก ์ฝ๋๋ฅผ ์ ์ฅํ ๋๋ง๋ค ์ฆ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋ณผ ์ ์์ต๋๋ค.
์์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค: DALLยทE๋ฅผ ์ค์ฌ์ผ๋ก ์ด๋ฏธ์ง ์์ฑ UI๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค. ๊ฐ๋จํ๊ฒ ํ๊ธฐ ์ํด OpenAI API๋ฅผ ํธ์ถํ์ง๋ง, ์ด๋ฅผ ๋ก์ปฌ์์ ์คํ๋๋ ML ๋ชจ๋ธ๋ก ๋์ฒดํ ์ ์์ต๋๋ค.
ย
ย
์ด๊ฒ์ด ์์ฑ๋ ์ฝ๋์ ๋๋ค. ์ด ๋ชจ๋ ๊ฒ์ ํ๋์ Python ํ์ผ์์ ์ด๋ฃจ์ด์ง๋๋ค!
import reflex as rx
import openai
openai.api_key = "YOUR_API_KEY"
class State(rx.State):
"""The app state."""
prompt = ""
image_url = ""
processing = False
complete = False
def get_image(self):
"""Get the image from the prompt."""
if self.prompt == "":
return rx.window_alert("Prompt Empty")
self.processing, self.complete = True, False
yield
response = openai.Image.create(prompt=self.prompt, n=1, size="1024x1024")
self.image_url = response["data"][0]["url"]
self.processing, self.complete = False, True
def index():
return rx.center(
rx.vstack(
rx.heading("DALLยทE"),
rx.input(placeholder="Enter a prompt", on_blur=State.set_prompt),
rx.button(
"Generate Image",
on_click=State.get_image,
is_loading=State.processing,
width="100%",
),
rx.cond(
State.complete,
rx.image(
src=State.image_url,
height="25em",
width="25em",
)
),
padding="2em",
shadow="lg",
border_radius="lg",
),
width="100%",
height="100vh",
)
# Add state and page to the app.
app = rx.App()
app.add_page(index, title="reflex:DALLยทE")
UI๋ถํฐ ์์ํด๋ด ์๋ค.
def index():
return rx.center(
...
)
index
ํจ์๋ ์ฑ์ ํ๋ก ํธ์๋๋ฅผ ์ ์ํฉ๋๋ค.
center
, vstack
, input
, button
๊ณผ ๊ฐ์ ๋ค์ํ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก ํธ์๋๋ฅผ ๊ตฌ์ถํฉ๋๋ค.
์ปดํฌ๋ํธ๋ค์ ๋ณต์กํ ๋ ์ด์์์ ๋ง๋ค๊ธฐ ์ํด ์๋ก ์ค์ฒฉ๋ ์ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ํค์๋ ์ธ์๋ฅผ ์ฌ์ฉํ์ฌ CSS์ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ์คํ์ผ์ ์ง์ ํ ์ ์์ต๋๋ค.
Reflex๋ ์์ํ๊ธฐ ์ํ 60๊ฐ ์ด์์ ๊ธฐ๋ณธ ์ปดํฌ๋ํธ๋ฅผ ์ ๊ณตํ๊ณ ์์ต๋๋ค. ๋ ๋ง์ ์ปดํฌ๋ํธ๋ฅผ ์ถ๊ฐํ๊ณ ์์ผ๋ฉฐ, ์์ ๋ง์ ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ๋ ๊ฒ๋ ์ฝ์ต๋๋ค.
Reflex๋ UI๋ฅผ State ํจ์๋ก ํํํฉ๋๋ค.
class State(rx.State):
"""The app state."""
prompt = ""
image_url = ""
processing = False
complete = False
state๋ ์ฑ์์ ๋ณ๊ฒฝ๋ ์ ์๋ ๋ชจ๋ ๋ณ์(vars๋ก ๋ถ๋ฆผ)์ ์ด๋ฌํ ๋ณ์๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์๋ฅผ ์ ์ํฉ๋๋ค.
์ฌ๊ธฐ์ state๋ prompt
์ image_url
๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ๋ํ processing
๊ณผ complete
๋ผ๋ ๋ถ๋ฆฌ์ธ ๊ฐ์ด ์์ต๋๋ค. ์ด ๊ฐ๋ค์ ์ํ ์งํ๋ฅ ๊ณผ ์ด๋ฏธ์ง๋ฅผ ํ์ํ ๋๋ฅผ ๋ํ๋
๋๋ค.
def get_image(self):
"""Get the image from the prompt."""
if self.prompt == "":
return rx.window_alert("Prompt Empty")
self.processing, self.complete = True, False
yield
response = openai.Image.create(prompt=self.prompt, n=1, size="1024x1024")
self.image_url = response["data"][0]["url"]
self.processing, self.complete = False, True
State ๋ด์์, state vars๋ฅผ ๋ณ๊ฒฝํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ผ๊ณ ๋ถ๋ฆฌ๋ ํจ์๋ฅผ ์ ์ํฉ๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ Reflex์์ state๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ๋ฒํผ์ ํด๋ฆญํ๊ฑฐ๋ ํ ์คํธ ์์์ ์ ๋ ฅํ๋ ๊ฒ๊ณผ ๊ฐ์ด ์ฌ์ฉ์ ๋์์ ์๋ตํ์ฌ ํธ์ถ๋ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋์์ ์ด๋ฒคํธ๋ผ๊ณ ํฉ๋๋ค.
DALLยทE. ์ฑ์๋ OpenAI API์์ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ค๋ get_image
์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ์์ต๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ์ค๊ฐ์ yield
๋ฅผ ์ฌ์ฉํ๋ฉด UI๊ฐ ์
๋ฐ์ดํธ๋ฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด UI๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๋์์ ์
๋ฐ์ดํธ๋ฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก, ์ฑ์ ์ ์ํฉ๋๋ค.
app = rx.App()
์ฑ์ ๋ฃจํธ์์ index ์ปดํฌ๋ํธ๋ก ํ์ด์ง๋ฅผ ์ถ๊ฐํฉ๋๋ค. ๋ํ ํ์ด์ง ๋ฏธ๋ฆฌ๋ณด๊ธฐ/๋ธ๋ผ์ฐ์ ํญ์ ํ์๋ ์ ๋ชฉ๋ ์ถ๊ฐํฉ๋๋ค.
app.add_page(index, title="DALL-E")
์ฌ๋ฌ ํ์ด์ง๋ฅผ ์ถ๊ฐํ์ฌ ๋ฉํฐ ํ์ด์ง ์ฑ์ ๋ง๋ค ์ ์์ต๋๋ค.
๐ ๋ฌธ์ ย | ย ๐๏ธ ๋ธ๋ก๊ทธ ย | ย ๐ฑ ์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ย | ย ๐ผ๏ธ ๊ฐค๋ฌ๋ฆฌ ย | ย ๐ธ ๋ฐฐํฌ ย
Reflex๋ 2022๋ 12์ Pynecone์ด๋ผ๋ ์ด๋ฆ์ผ๋ก ์ถ์๋์์ต๋๋ค.
2023๋ 7์ ํ์ฌ, ์ฐ๋ฆฌ๋ Public Beta ์ํ์ ์์ต๋๋ค.
- โ Public Alpha: ๋๊ตฌ๋ Reflex๋ฅผ ์ค์นํ๊ณ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์๋ ์์ง๋ง ์ ๊ทน์ ์ผ๋ก ์์ ํฉ๋๋ค.
- ๐ถ Public Beta: ๋น์์ ์ ์ฉ๋๋ก ์ถฉ๋ถํ ์์ ์ ์ ๋๋ค.
- Public Hosting Beta: ์ ํ์ ์ผ๋ก, Reflex์์ ์ฑ์ ๋ฐฐํฌํ๊ณ ํธ์คํ ํ ์ ์์ต๋๋ค!
- Public : Reflex๋ ํ๋ก๋์ ์ค๋น๋ฅผ ๋ง์ณค์ต๋๋ค.
Reflex๋ ๋งค์ฃผ ์๋ก์ด ๋ฆด๋ฆฌ์ฆ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค! ์ต์ ์ ๋ณด๋ฅผ ํ์ธํ๋ ค๋ฉด โญ Star์ ๐ Watch๋ฅผ ๋๋ฌ ์ด ์ ์ฅ์๋ฅผ ํ์ธํ์ธ์.
์ฐ๋ฆฌ๋ ๋ชจ๋ ๊ธฐ์ฌ๋ฅผ ํ์ํฉ๋๋ค! ์๋๋ Reflex ์ปค๋ฎค๋ํฐ์ ์ฐธ์ฌํ๋ ์ข์ ๋ฐฉ๋ฒ์ ๋๋ค.
- Discord ์ฐธ์ฌ: ์ฐ๋ฆฌ์ Discord๋ Reflex ํ๋ก์ ํธ์ ๋ํ ๋์์ ๋ฐ๊ณ ๊ธฐ์ฌํ๋ ๋ฐฉ๋ฒ์ ๋ ผ์ํ๋ ์ต๊ณ ์ ์ฅ์์ ๋๋ค.
- GitHub Discussions: ์ถ๊ฐํ๊ณ ์ถ์ ๊ธฐ๋ฅ์ด๋ ํผ๋์ค๋ฝ๊ฑฐ๋ ํด๊ฒฐ์ด ํ์ํ ๊ฒ๋ค์ ๋ํด ์ด์ผ๊ธฐํ๋ ์ข์ ๋ฐฉ๋ฒ์ ๋๋ค.
- GitHub Issues: ์ด๊ฒ์ ๋ฒ๊ทธ๋ฅผ ๋ณด๊ณ ํ๋ ํ๋ฅญํ ๋ฐฉ๋ฒ์ ๋๋ค. ๋ํ, ๊ธฐ์กด์ ์ด์๋ฅผ ํด๊ฒฐํ๊ณ PR์ ์ ์ถํ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ๋ ๋ฅ๋ ฅ์ด๋ ๊ฒฝํ์ ์๊ด์์ด ์ ๊ทน์ ์ผ๋ก ๊ธฐ์ฌ์๋ฅผ ์ฐพ๊ณ ์์ต๋๋ค.
Reflex๋ ์คํ์์ค์ด๋ฉฐ Apache License 2.0๋ก ๋ผ์ด์ ์ค๊ฐ ๋ถ์ฌ๋ฉ๋๋ค.