+ Searching for Pynecone? You are in the right repo. Pynecone has been renamed to Reflex. +
English | 简体中文 | 繁體中文 | Türkçe | हिंदी | Português (Brasil) | Italiano | Español | 한국어 | 日本語 | Deutsch | Persian (پارسی) | Tiếng Việt
Reflex is a library to build full-stack web apps in pure Python.
Key features:
- Pure Python - Write your app's frontend and backend all in Python, no need to learn Javascript.
- Full Flexibility - Reflex is easy to get started with, but can also scale to complex apps.
- Deploy Instantly - After building, deploy your app with a single command or host it on your own server.
See our architecture page to learn how Reflex works under the hood.
Open a terminal and run (Requires Python 3.9+):
pip install reflex
Installing reflex
also installs the reflex
command line tool.
Test that the install was successful by creating a new project. (Replace my_app_name
with your project name):
mkdir my_app_name
cd my_app_name
reflex init
This command initializes a template app in your new directory.
You can run this app in development mode:
reflex run
You should see your app running at http://localhost:3000.
Now you can modify the source code in my_app_name/my_app_name.py
. Reflex has fast refreshes so you can see your changes instantly when you save your code.
Let's go over an example: creating an image generation UI around DALL·E. For simplicity, we just call the OpenAI API, but you could replace this with an ML model run locally.
Here is the complete code to create this. This is all done in one Python file!
import reflex as rx
import openai
openai_client = openai.OpenAI()
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_client.images.generate(
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", font_size="1.5em"),
rx.input(
placeholder="Enter a prompt..",
on_blur=State.set_prompt,
width="25em",
),
rx.button(
"Generate Image",
on_click=State.get_image,
width="25em",
loading=State.processing
),
rx.cond(
State.complete,
rx.image(src=State.image_url, width="20em"),
),
align="center",
),
width="100%",
height="100vh",
)
# Add state and page to the app.
app = rx.App()
app.add_page(index, title="Reflex:DALL-E")
Let's start with the UI.
def index():
return rx.center(
...
)
This index
function defines the frontend of the app.
We use different components such as center
, vstack
, input
, and button
to build the frontend. Components can be nested within each other
to create complex layouts. And you can use keyword args to style them with the full power of CSS.
Reflex comes with 60+ built-in components to help you get started. We are actively adding more components, and it's easy to create your own components.
Reflex represents your UI as a function of your state.
class State(rx.State):
"""The app state."""
prompt = ""
image_url = ""
processing = False
complete = False
The state defines all the variables (called vars) in an app that can change and the functions that change them.
Here the state is comprised of a prompt
and image_url
. There are also the booleans processing
and complete
to indicate when to disable the button (during image generation) and when to show the resulting image.
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_client.images.generate(
prompt=self.prompt, n=1, size="1024x1024"
)
self.image_url = response.data[0].url
self.processing, self.complete = False, True
Within the state, we define functions called event handlers that change the state vars. Event handlers are the way that we can modify the state in Reflex. They can be called in response to user actions, such as clicking a button or typing in a text box. These actions are called events.
Our DALL·E. app has an event handler, get_image
to which get this image from the OpenAI API. Using yield
in the middle of an event handler will cause the UI to update. Otherwise the UI will update at the end of the event handler.
Finally, we define our app.
app = rx.App()
We add a page from the root of the app to the index component. We also add a title that will show up in the page preview/browser tab.
app.add_page(index, title="DALL-E")
You can create a multi-page app by adding more pages.
📑 Docs | 🗞️ Blog | 📱 Component Library | 🖼️ Templates | 🛸 Deployment
Reflex launched in December 2022 with the name Pynecone.
As of February 2024, our hosting service is in alpha! During this time anyone can deploy their apps for free. See our roadmap to see what's planned.
Reflex has new releases and features coming every week! Make sure to ⭐ star and 👀 watch this repository to stay up to date.
We welcome contributions of any size! Below are some good ways to get started in the Reflex community.
- Join Our Discord: Our Discord is the best place to get help on your Reflex project and to discuss how you can contribute.
- GitHub Discussions: A great way to talk about features you want added or things that are confusing/need clarification.
- GitHub Issues: Issues are an excellent way to report bugs. Additionally, you can try and solve an existing issue and submit a PR.
We are actively looking for contributors, no matter your skill level or experience. To contribute check out CONTRIBUTING.md
Reflex is open-source and licensed under the Apache License 2.0.
reflex's People
Forkers
gergomiklos raxbits ipvr9 tanglespace prrpigeon jai-parwani-1 sjbat kkovary daodaoliang playing332 mbrukman evenfly littleroc hardwaylinka liangwen ranjian0 ecrespo paul-sx tangyin88 wjdz99 ngocvinhvu murilo-cunha pysqz redseal798 gamertttt forhonourlx aod321 elijahahianyo denisgolius muddi900 lendemor jangkyumin 3chamchi justini0715 andy-verstraeten evisolpxe wooiljeong adieka86 techthiyanes monolith-kh chengfai guliomirbekova9 muratone lyrl stickmemory karamuh pickmoment supernova-z313 lorikmot vania123520 nadia22033 victor7775915 jujumilk3 celestialized cclauss tomatoisfruit qu3vipon saarthakmaini evolution-ant suarzac siddht1 agentmishra iuriimattos2 rasantis akankushjnvku chibaodebengbengxiong zby13857238876 anshika3113 vvanisimovv pnblam myeongji-kim mfaisalpnec anupgoenka tommydew42 ukaserge vishalsingh17 lumiagg l-uxxx r0b2g1t bobwerk it5-j05h pandeyashish17 luka-slogup thavocado therahulyadav chittellachaitanya98 furqonat abdoiiii kwazetop dev-robasi liudaolunboluo ausbeldev shehanxdev golang-everyday necatituran tangweejieleslie kumardeepam peteryusuke johnm-kahura ken-nahreflex's Issues
Ability of put any HTML to App
As you know, lots of Python plotting libraries support to output the result to HTML. Take PyEcharts for example, just use your_graph_obj.render_notebook()
, and put the output to App, you got a wonderful graph based on Echarts.
It can let us support more plotting libraries with just a bit work.
Add support for React hooks
Hi guys, cool project! I'm trying to migrate a basic Chakra + FastAPI app to Pynecone but a bit stuck on implementing the classic Chakra ColorModeSwitcher component.
Is there any way currently to access the color mode hooks? I imagine there are use cases beyond these hooks, but being able to use hooks from other libraries.
Example component to implement:
import * as React from "react"
import {
useColorMode,
useColorModeValue,
IconButton,
IconButtonProps,
} from "@chakra-ui/react"
import { FaMoon, FaSun } from "react-icons/fa"
type ColorModeSwitcherProps = Omit<IconButtonProps, "aria-label">
export const ColorModeSwitcher: React.FC<ColorModeSwitcherProps> = (props) => {
const { toggleColorMode } = useColorMode()
const text = useColorModeValue("dark", "light")
const SwitchIcon = useColorModeValue(FaMoon, FaSun)
return (
<IconButton
size="md"
fontSize="lg"
variant="ghost"
color="current"
marginLeft="2"
onClick={toggleColorMode}
icon={<SwitchIcon />}
aria-label={`Switch to ${text} mode`}
{...props}
/>
)
}
Don't show stack traces in prod
Currently if the event handler throws and exception, the stack trace is alerted on the browser. We should keep this enabled in dev mode, but have a cleaner solution when running in production.
Add documentation for pc.span
The span component currently doesn't have documentation.
Event Trigger Lambda Arguments Error
Describe the bug
Lambda need to be able to take in arguments other than ints. Currently non in arguments throw errors for event triggers that use lambdas
To Reproduce
class State(pc.State):
choices = ["A", "B", "C"]
def set_choice(self, index: int, answer: str):
self.choices[index] = answer
self.choices = self.choices
def index():
return pc.vstack(
pc.heading(State.choices),
pc.button(
"First",
on_click= lambda: State.set_choice(0, "Changed")
),
pc.button(
"Second",
on_click= lambda: State.set_choice(1, "Changed")
),
pc.button(
"Third",
on_click= lambda: State.set_choice(2, "Changed")
)
)
Expected behavior
Should set the index of the choices
to changed depending on button clicked.
Screenshots
NA
** Specifics (please complete the following information):**
- Python Version: 3.10
- Pynecone Version: 0.1.8
- OS: Mac
- Browser (Optional):
Additional context
None
Run in prod mode without setting api variable
Currently you need to include a line like
api = app.api
to run your app in prod mode. We should somehow infer this.
Add way to clear uncontrolled input
Currently in order to clear the value of a pc.input
you need to make it a controlled input (i.e. set the value
and on_change
props together). This has the downside of making a network call with every keystroke. We need a more performant way to achieve this.
Possibly react refs?
Handle dynamic routes
We should handle these: https://nextjs.org/docs/routing/dynamic-routes
Fix Datatable API
Have oneway to support data frames and list.
Add Upload to Pynecone
Have the ability to upload images and other files.
Allow state var to be input to select form
I might be missing something, but at the moment it seems like state vars cannot be used as inputs to the select form. If possible this would be a really nice feature for creating dynamic dropdown options (for instance values retrieved via API calls).
Specify extra bun packages in pcconfig
Currently if you want to add extra bun packages (i.e. to wrap your own react components) you need to manually do a bun add
in the .web
directory. Instead, we should specify this all in the pcconfig.py
to keep with our philosophy of not having to touch the .web
folder. Also, it has the advantage that we can add the packages again every time we rerun pc init
.
[Question] is there a way to pass a parameter to pc.button(is_active=State.is_active)?
Hi again,
I'd like to pass a parameter in the State.is_active(self, index)
method so that I can distinguish 2 buttons sharing the same state. Is it possible? Using a lambda like in the twitter example?
pc.button(
pc.icon(tag="AddIcon", color="white", height="1em"),
on_click=lambda: HomeState.follow_user(friend.username),
bg="rgb(29, 161, 242)",
),
I tried something like that but no luck
class State(pc.State):
def is_active(self, index: int) -> bool:
return self.butstate[index]
...
return pc.button(
model.title,
size="lg",
on_click=State.switch,
style=button_style,
is_active=lambda: State.is_active(0),
)
Error: TypeError: Object of type function is not JSON serializable
replace `requests` with `httpx`
httpx
is a requests-like Python network package. It can be a drop-in replacement of requests
.
Just search for any use of requests and I only found the command line tool pc
use it, for a subcommand deploy
which is unused now, so feel free to leave it there until we release the deploy feature.
Add Button Group Docs
Add button group docs this is missing.
Convert code to reactjs and nextjs
Title says it all,would be cool to be added
Add Meta Tags to App
Right now we can just do title, we need to add the rest of the meta tags
Please make this product cross-platform. It does not run on Windows right now.
Looking through a config file we see this:
config = pc.Config(
app_name="dalle",
bun_path="$HOME/.bun/bin/bun",
db_url="sqlite:///pynecone.db",
env=pc.Env.DEV,
)
This will not run on windows. There may be other unix-isms throughout this product. Please make this product platform-neutral.
Make pc run prod work without redis
- If redis is not available, we should run gunicorn with only one worker.
- Currently it will be buggy since each worker has its own state dict.
Indexing not working for props in state.
Describe the bug
Indexing vars in the state is not working.
To Reproduce
class ArgState(State):
colors: list[str] = ["rgba(222,44,12)", "white", "#007ac2"]
def change_color(self, color, index):
self.colors[index] = color
# Colors must be set not mutated (Warning below example about mutations.)
self.colors = self.colors
def index():
return pc.hstack(
pc.input(default_value=ArgState.colors[0], on_blur=lambda c: ArgState.change_color(c, 0), bg=ArgState.colors[0]),
pc.input(on_blur=lambda c: ArgState.change_color(c, 1), bg=ArgState.colors[1]),
pc.input(on_blur=lambda c: ArgState.change_color(c, 2), bg=ArgState.colors[2]),
)
Expected behavior
Be able to index into the colors list.
If on Desktop (please complete the following information):
Chrom on macOS Monterey.
Error running pc init
──────────────────────────────────────────────── Starting Pynecone App ────────────────────────────────────────────────
─────────────────────────────────────────────── Installing Dependencies ───────────────────────────────────────────────
Traceback (most recent call last):
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in run_code
exec(code, run_globals)
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\Scripts\pc.exe_main.py", line 7, in
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\typer\main.py", line 214, in call
return get_command(self)(*args, **kwargs)
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 1130, in call
return self.main(*args, **kwargs)
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 1055, in main
rv = self.invoke(ctx)
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 1657, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\click\core.py", line 760, in invoke
return __callback(*args, **kwargs)
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\typer\main.py", line 532, in wrapper
return callback(**use_params) # type: ignore
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\pynecone\pc.py", line 78, in run
frontend_cmd(app)
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\pynecone\utils.py", line 363, in run_frontend
setup_frontend(app)
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\pynecone\utils.py", line 345, in setup_frontend
install_dependencies()
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\site-packages\pynecone\utils.py", line 320, in install_dependencies
subprocess.call([get_bun_path(), "install"], cwd=constants.WEB_DIR, stdout=PIPE)
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 345, in call
with Popen(*popenargs, **kwargs) as p:
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 966, in init
self._execute_child(args, executable, preexec_fn, close_fds,
File "C:\Users\bojan\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1435, in _execute_child
hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified
I have just installed pynecone,i have py and node,everything seems fine on my end
Accordion item cannot be closed
Problem:
When defining an accordion, all the
accordion_panel()
start closed.
However, once opened, it is impossible to close them again by clicking on their relatedaccordion_button()
.
Expected:
Clicking an
accordion_button()
should close the relatedaccordion_panel()
.
How to reproduce:
Use the examples in the documentation at Accordion
Edit:
Oops, according to #3 it's already solved.
However default behavior for me (and in the doc too) still seems to be that
allow_toggle=False
.
I'm using Version : 0.1.8
[Question] using pc.button inline styling, how to set hover and selected color?
Hi,
what are the CSS properties to set the button background hover and active colors ?
button_style = {
"color": "black",
"background": "white",
}
return pc.button(
model.title,
size="lg",
on_click=State.switch,
style=button_style,
is_active=State.butstate,
)
thanks!
Accordian does not collapse
TypeError: Object of type EventHandler is not JSON serializable
Trying to put together a simple app that queries an API endpoint, gets the result of the query, and displays it in a modal. Using this as a POC to understand how to work with pyncone. I am receiving the following error, and cannot determine where its coming from.
───────────────────────────────────────────────────────────────────────────────── Starting Pynecone App ──────────────────────────────────────────────────────────────────────────────────
Traceback (most recent call last):
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/bin/pc", line 8, in <module>
sys.exit(main())
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/typer/main.py", line 214, in __call__
return get_command(self)(*args, **kwargs)
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
return self.main(*args, **kwargs)
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/click/core.py", line 1055, in main
rv = self.invoke(ctx)
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/click/core.py", line 760, in invoke
return __callback(*args, **kwargs)
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/typer/main.py", line 532, in wrapper
return callback(**use_params) # type: ignore
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/pynecone/pc.py", line 68, in run
app = utils.get_app()
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/pynecone/utils.py", line 314, in get_app
app = __import__(module, fromlist=(constants.APP_VAR,))
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/cmdb_lookup/cmdb_lookup.py", line 53, in <module>
app.add_page(index)
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/pynecone/app.py", line 220, in add_page
component = component if isinstance(component, Component) else component(*args)
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/cmdb_lookup/cmdb_lookup.py", line 32, in index
pc.modal(
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/pynecone/components/component.py", line 278, in create
return cls(children=children, **props)
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/pynecone/components/component.py", line 101, in __init__
kwargs[key] = Var.create(value)
File "/Users/pacea/workspace/websites/pynecone/cmdb_lookup/.venv/lib/python3.10/site-packages/pynecone/var.py", line 67, in create
name = json.dumps(value) if not isinstance(value, str) else value
File "/usr/local/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/usr/local/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/usr/local/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type EventHandler is not JSON serializable
My app code looks like this:
"""Welcome to Pynecone! This file outlines the steps to create a basic app."""
from pcconfig import config
import pynecone as pc
from .state import State, CMDBState
def index():
return pc.center(
pc.vstack(
pc.heading("CMDB Query", font_size="2em"),
pc.box("Enter the Application CI Value to query for in the CMDB"),
pc.input(
placeholder="Application CI Value",
on_blur=CMDBState.set_application_ci,
size="small",
variant="outline",
),
pc.button(
"Submit",
bg="blue",
color="white",
size="md",
on_click=CMDBState.get_value,
),
pc.cond(
CMDBState.processing,
pc.circular_progress(is_indeterminate=True),
pc.cond(
CMDBState.completed,
pc.modal(
pc.modal_overlay(
pc.modal_content(
pc.modal_header(f"Entry for {CMDBState.application.ApplicationCI}"),
pc.modal_body(pc.box(CMDBState.application)),
pc.modal_footer(pc.button("Close", on_click=CMDBState.toggle_modal)),
)
),
is_open=CMDBState.toggle_modal,
),
),
),
spacing="1.5em",
font_size="2em",
),
padding_top="10%",
)
app = pc.App(state=State)
app.add_page(index)
app.compile()
and my state looks like:
import pynecone as pc
import json
import requests
class Application(pc.Base):
ApplicationCI: str
ServiceNowId: str
Domain: int
BusinessRegion: str
Confidentiality: str
BusinessSubDomain: str
Availability: str
BusinessDomain: str
SME: str
RTO: int
RPO: int
Integrity: str
CostCenter: str
BusinessArea: str
Owner: str
ApplicationSupport: str
Manager: str
ExecutiveManager: str
class State(pc.State):
pass
class CMDBState(State):
applicationCI: str = ""
application: Application = None
completed: bool = False
processing: bool = False
retrieved: bool = False
def set_application_ci(self, value):
self.applicationCI = value
def toggle_modal(self):
self.retrieved = not (self.show_modal)
def get_value(self):
# set processing to true to show the loading spinner
self.processing = True
url = f"https://someurl/?type=name&id=${self.applicationCI}"
response = requests.get(url, verify=False)
response = json.loads(response.text)
if response == {}:
# if the response is empty, set retrieved to false to hide the todo
self.retrieved = False
# set processing to false to hide the loading spinner
self.processing = False
return
self.application = Application(**response)
# set processing to false to hide the loading spinner
self.processing = False
# set retrieved to true to show the todo
self.retrieved = True
any help would be greatly appreciated
Audio Component?
Does there exist a component like similar to Streamlit audio? Or plans to implement? Would be lovely :)
Create an upload component
It would be great if we could upload files using Pynecone.
Detect if user forgot to pc init
We should throw a nicer error message if someone does pc run
before they pc init
.
Passing strings to event handler functions via lambda
Describe the bug
Using a lambda function to bundle args to an event handler function works if the args are numbers, but not if they are strings
To Reproduce
Steps to reproduce the behavior:
The code
pc.button("STOP", on_click=lambda: State.status_change(index, "stop"))
Compiles the string literal to a bareword in the javascript:
<Button onClick={() => Event([E("state.status_change", {index:0,change:stop})])}>
{`STOP`}</Button>
This causes an error as the event payload is not transmitted properly
Traceback (most recent call last):
File "/home/p/.asdf/installs/python/3.10.6/lib/python3.10/site-packages/pynecone/state.py", line 357, in process
events = fn(**event.payload)
TypeError: State.status_change() missing 1 required positional argument: 'change'
The state function is
def status_change(self, index, change):
self.services[index].status = change
self.services = self.services
Expected behavior
It would be expected to compile to the following Javascript
<Button onClick={() => Event([E("state.status_change", {index:0,change:"stop"})])}>
{`STOP`}</Button>
The offending code is likely in pynecone/utils.py at
def format_event(event_spec: EventSpec) -> str:
"""Format an event.
Args:
event_spec: The event to format.
Returns:
The compiled event.
"""
args = ",".join([":".join((name, val)) for name, val in event_spec.args])
return f"E(\"{format_event_fn(event_spec.handler.fn)}\", {wrap(args, '{')})"
I think val needs to be wrapped and escaped if it is a string
** Specifics (please complete the following information):**
- Python Version: 3.10.6
- Pynecone Version: pynecone-io==0.1.8
- OS: Ubuntu 22.04
- Browser (Optional):
Add documentation for pc.Base
Docs to show how to use pc.Base
in state vars.
Add pc.iframe
Add an iframe component would be nice additional and should be fairly easy to add.
Make some dependencies optional
Just installed this library use Poetry and poetry show --tree
seems to be that:
pynecone 0.0.70 Build your CLI with ease
├── certifi *
├── jinja2 *
│ └── markupsafe >=2.0
├── keyring *
│ ├── (some deps)
├── pika *
├── python-dotenv *
├── pyyaml *
├── requests *
│ ├── (some-deps)
├── requests-toolbelt *
│ └── (some deps)
├── sqlalchemy *
│ └── greenlet !=0.4.17
└── tabulate *
When I want to use MongoDB as my database, I don't use the internal ORM provided by Pynecone, and the dependence SQLAlchemy
is not nesserary for me. We can detect if user installed this library when they try to import a module which need it, and this dependence should not be included by default.
extras
in pyproject.toml
may be helpful for this, we can install the ORM-ready version with pynecone[orm]
, and all the optional dependencies installed version with pynecone[all]
.
By the way, httpx
is a better replacement for requests
, it support HTTP/2 and asyncio, and may be helpful for the support of async function in next versions. If you think that is a good idea, I will open another issue about it.
Visually Hidden (Useful for Screen Readers)
Integrate the VisuallyHidden Chakra-UI component, which is a common technique used in web accessibility to hide content from the visual client, but keep it readable for screen readers.
please make the functions/objects params to be detectable by pylance
Added ReInit to detect new version
When updating pynecone the reinit should detect a new version has been changed and automatically init on the next bug
Enable prod mode on windows
Currently pc run in prod mode has Unix assumptions, we should abstract this out.
Surpress Fast Refresh Warning
NextJs is giving the warning:
warn - Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works
We should surprise this.
Computed Var example doesn't work if @pc.computed handler doesn't specify return type
Describe the bug
The computed vars example no longer works if the return type annotation is removed. It shows an error as follows:
Traceback (most recent call last):
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/site-packages/uvicorn/subprocess.py", line 76, in subprocess_started
target(sockets=sockets)
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/site-packages/uvicorn/server.py", line 60, in run
return asyncio.run(self.serve(sockets=sockets))
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete
return future.result()
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/site-packages/uvicorn/server.py", line 67, in serve
config.load()
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/site-packages/uvicorn/config.py", line 458, in load
self.loaded_app = import_from_string(self.app)
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/site-packages/uvicorn/importer.py", line 21, in import_from_string
module = importlib.import_module(module_str)
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/Users/kabir/Repos/translator/./translator/translator.py", line 51, in <module>
app.add_page(index, title=title)
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/site-packages/pynecone/app.py", line 169, in add_page
component = component if isinstance(component, Component) else component()
File "/Users/kabir/Repos/translator/./translator/translator.py", line 41, in index
pc.input(value=State.translation),
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/site-packages/pynecone/components/component.py", line 202, in create
return cls(children=children, **attrs)
File "/Users/kabir/.pyenv/versions/3.10.2/lib/python3.10/site-packages/pynecone/components/component.py", line 132, in __init__
assert expected_type == Any or issubclass(
TypeError: issubclass() arg 1 must be a class
To Reproduce
Use this code but remove the -> str
.
Expected behavior
I expected this to work, or provide a descriptive error message saying that a return type is required. In general, I expected the entire API surface to work with or without type annotations.
Add Setup to Contributing Guide.
Fix firefox rendering issue
The main website doesn't render correctly on Firefox, the grids look all weird.
Add clear way to export to static site
For apps with no state (only frontends), it should be possible to export the Pynecone app to a static site, to be hosted on S3, Github Pages, etc.
We just have to run next export
on the web directory after compiling the app. We already do this when running the app in production mode, but we can maybe add a command pc export
that will only do this portion of it.
Computed Vars optimization
Cool framework!
There are keys dropped when typing in the <input>
field for the 'Computed Vars' demo in the docs
E.g. typing 'Hello World' at normal speed shows as 'HELO WLD' in the computed heading.
Issue with radio_group and pc.model
Describe the bug
radio_group works well with the options are defined as a global list but when read from a pc.model it doesn't work
To Reproduce
"""Welcome to Pynecone! This file outlines the steps to create a basic app."""
from pcconfig import config
from typing import List
import pynecone as pc
docs_url = "https://pynecone.io/docs/getting-started/introduction"
filename = f"{config.app_name}/{config.app_name}.py"
class RadioModel(pc.Model, table=True):
title: str
options: List[str]
tooltip: str
class State(pc.State):
"""The app state."""
answer: str
@pc.var
def get_radiomodel(self) -> List[RadioModel]:
return [ RadioModel(title="this is a title", options = ["option 1", "option 2"], tooltip="easy")]
def set_answer(self, test):
self.answer = answer
def index():
return pc.center(
pc.vstack(
pc.foreach(
State.get_radiomodel, lambda a_model: display_form(a_model)
),
spacing="1.5em",
font_size="2em",
),
padding_top="10%",
)
options = [ "option 3", "options 4"]
def display_form(model: RadioModel):
return pc.form_control(
# pc.badge(State.answer, color_scheme="green"),
pc.radio_group(
model.options, #options,
on_change=State.set_answer,
),
pc.form_helper_text(model.tooltip),
is_required=True,
)
# Add state and page to the app.
app = pc.App(state=State)
app.add_page(index)
app.compile()
Expected behavior
A clear and concise description of what you expected to happen.
** Specifics (please complete the following information):**
- Python Version: 3.8.10
- Pynecone Version: 0.1.8
- OS: WSL2
- Browser (Optional): Edge
Additional context
Add any other context about the problem here.
Possible wrong name in ResponsiveGrid doc
On the doc page for ResponsiveGrid, there is the following text:
SimpleGrid provides a friendly interface to create responsive grid layouts with ease. SimpleGrid composes Box so you can pass all the Box props and css grid props with addition to the ones below.
SimpleGrid is not mentionned anywhere else, shouldn't it be ResponsiveGrid?
Ways to disable line feed in datatable?
I want to display some data, with a column called article title which can be up to 30 chars ( If it is too long, I will strip it ), but I want to enable horizontal scoll when screen width is too small to display all the chars.
I tried to add white-space: nowrap
to the root node of datatable in DevTools, and it is work for my case, but when I turns to add kwargs in pc.datatable
, it doesn't work.
Is the attr has been attched to a wrong DOM node? It is a Bug to fix or there are another way to do it?
Create Fragment Component
We should create a component to wrap React fragments: https://reactjs.org/docs/fragments.html
Setting the value of an input to a pc.computed does not work
Describe the bug
In the Computed Vars example, I tried changing the pc.heading(UppercaseState.upper_text)
to pc.input(value=UppercaseState.upper_text)
but this does not work. It does not work when I set this "computed input" to be controlled, either.
To Reproduce
(Described above.)
Expected behavior
I expected this to work, since setting the value of one input to the output of another input is not uncommon. I would then have tried to use an on_change
handler on the computed input to store if the user edited the translation output and what they edited it to. (I had a similar use case in the research study interface I’d demoed.)
If on Desktop (please complete the following information):
Firefox 106 on macOS Monterey.
`pc run` fails on WSL2
Hi,
OS: Ubuntu on WSL2 on Win10
Env: virtualenv with pynecone installed
NodeJS 16.18.1
Python 3.8.10
I just tried pynecone (pc init
and pc run
) and I have this error:
(.venv) matt@wsl2:~/projects/git/pynecone$ pc init
[21:03:20] Initialize the app directory. pc.py:31
Initializing the web directory. pc.py:47
Finished Initializing: pynecone pc.py:51
(.venv) matt@wsl2:~/projects/git/pynecone$ pc run
───────────────────────────────────────────────────────────────────────────────────────────── Starting Pynecone App ─────────────────────────────────────────────────────────────────────────────────────────────
Traceback (most recent call last):
File "/home/matt/projects/git/pynecone/.venv/bin/pc", line 8, in <module>
sys.exit(main())
File "/home/matt/projects/git/pynecone/.venv/lib/python3.8/site-packages/typer/main.py", line 214, in __call__
return get_command(self)(*args, **kwargs)
File "/home/matt/projects/git/pynecone/.venv/lib/python3.8/site-packages/click/core.py", line 1130, in __call__
return self.main(*args, **kwargs)
File "/home/matt/projects/git/pynecone/.venv/lib/python3.8/site-packages/click/core.py", line 1055, in main
rv = self.invoke(ctx)
File "/home/matt/projects/git/pynecone/.venv/lib/python3.8/site-packages/click/core.py", line 1657, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/matt/projects/git/pynecone/.venv/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/matt/projects/git/pynecone/.venv/lib/python3.8/site-packages/click/core.py", line 760, in invoke
return __callback(*args, **kwargs)
File "/home/matt/projects/git/pynecone/.venv/lib/python3.8/site-packages/typer/main.py", line 532, in wrapper
return callback(**use_params) # type: ignore
File "/home/matt/projects/git/pynecone/.venv/lib/python3.8/site-packages/pynecone/pc.py", line 68, in run
app = utils.get_app()
File "/home/matt/projects/git/pynecone/.venv/lib/python3.8/site-packages/pynecone/utils.py", line 314, in get_app
app = __import__(module, fromlist=(constants.APP_VAR,))
ModuleNotFoundError: No module named 'pynecone.pynecone'
pip freeze
anyio==3.6.2
async-timeout==4.0.2
certifi==2022.12.7
charset-normalizer==2.1.1
click==8.1.3
commonmark==0.9.1
fastapi==0.88.0
greenlet==2.0.1
gunicorn==20.1.0
h11==0.14.0
idna==3.4
plotly==5.11.0
pydantic==1.10.2
Pygments==2.13.0
pynecone-io==0.1.8
redis==4.4.0
requests==2.28.1
rich==12.6.0
sniffio==1.3.0
SQLAlchemy==1.4.41
sqlalchemy2-stubs==0.0.2a29
sqlmodel==0.0.8
starlette==0.22.0
tenacity==8.1.0
typer==0.4.2
typing-extensions==4.4.0
urllib3==1.26.13
uvicorn==0.20.0
Any idea
Ensure underscores convert to hyphens for path names
I was running into an issue using a page function that includes an underscore.
For example, if I use this:
def sign_up():
Instead of this:
def signup():
I'll get this error at /sign_up:
Unhandled Runtime Error
Error: Invariant: attempted to hard navigate to the same URL
After some exploration, I think it's because of the underscore.
I can fix the problem as follows:
app.add_page(sign_up, path="/sign-up")
I'm not sure why this is happening because in add_page()
you call utils.format_route(path)
, which should solve this.
If it helps, I'm importing this page as follows:
from pynecone_experiment.pages.sign_up import sign_up
Embedding Pynecone in other apps
One of the issues i had with streamlit (from what i remember) is that you can't easily embed streamlit into existing applications, and the same seems to be true here.
It would be really cool if i could do pynecone.run() from an existing app and bind state to existing modules. It would allow one to take existing APIs and wire them up quickly to a pyonecone GUI.
I know that is certainly easier said than done. Go ahead and close this issue if that is too far out of scope or isn't feasible.
Thank you for your efforts, pynecone is neat.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.