Compare commits

...

821 Commits

Author SHA1 Message Date
Masen Furer
98f50811f9
Override react-is@19.0.0 for recharts compatibility (#4857)
See https://github.com/recharts/recharts/issues/4558 for details.
2025-02-21 16:11:40 -08:00
Khaleel Al-Adhami
ee03415894
fix autoscroll on stateful children (#4858) 2025-02-21 15:09:25 -08:00
Khaleel Al-Adhami
8943341605
simplify toast banner logic (#4853)
* simplify toast banner logic

* expose toast

* default back to title and desc, and replace brs with new lines
2025-02-20 15:10:15 -08:00
benedikt-bartscher
836e8f8ce9
migrate to new react 19 context api (#4849) 2025-02-20 12:23:47 -08:00
Masen Furer
e891dbe6b9
pyproject.toml: bump to 0.7.2dev1 (#4851) 2025-02-20 12:23:14 -08:00
Khaleel Al-Adhami
c2917d46d5
simplify and fix set_color_mode (#4852)
* simplify and fix set_color_mode

* woops
2025-02-19 22:06:13 -08:00
Khaleel Al-Adhami
96086bcb0c
change error connecting to backend when backend is cold started (#4814)
* change error connecting to backend when backend is cold started

* do as simon wanted

* prefix with REFLEX
2025-02-19 15:09:13 -08:00
Khaleel Al-Adhami
6e4522c15c
react 19 time (#4848)
* react 19 time

* idk why

* better default for resolvedColorMode

* remove prints
2025-02-19 14:46:53 -08:00
Masen Furer
deb1f4f702
[ENG-4713] Cache pages which add states when evaluating (#4788)
* cache order of imports that create BaseState subclasses

* Track which pages create State subclasses during evaluation

These need to be replayed on the backend to ensure state alignment.

* Clean up: use constants, remove unused code

Handle closing files with contextmanager

* Expose app.add_all_routes_endpoint for flexgen

* Include .web/backend directory in backend.zip when exporting
2025-02-19 12:43:20 -08:00
Khaleel Al-Adhami
7a6c7123bd
treat hyphen as underscore in keys of styles (#4810)
* treat hyphen as underscore in keys of styles

* fix tests

* more nuanced conversions
2025-02-19 12:33:03 -08:00
Khaleel Al-Adhami
abab18e165
components deserve to be first class props (#4827)
* components deserve to be first class props

* default back to {}

* smarter yield

* how much does caching help?

* only hit the slower path on _are_fields_known

* remove the cache thingy

* cache the inner _get_component_prop_names

* oops

* dang it darglint

* refactor things a bit

* fix events
2025-02-19 11:27:33 -08:00
Masen Furer
762d975a87
Allow any user to set show_built_with_reflex=False in any mode (#4847) 2025-02-19 11:03:54 -08:00
Sumanth
405872aaf0
Wrapping extra components inside of the Context Menu Component (#4831)
* Wrapping extra components inside of the Context Menu Component  (partial fix for #4262) label, group, radio, radio_group

* removed unwanted changes

* removed codespell ignores and pyright type checking ignores

* remove misc changes

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2025-02-19 10:59:46 -08:00
Thomas Brandého
0a33cc3b8a
auto hide badge for pro+ users for cloud deployments (#4819)
* auto hide badge for pro+ users for cloud deployments

* update integrations tests

* fix integrations for real
2025-02-19 18:29:11 +01:00
Khaleel Al-Adhami
946b7bc25a
upgrade deps as per python 3.10 (#4842)
* upgrade deps as per python 3.10

* no need for that guy
2025-02-18 13:56:58 -08:00
Khaleel Al-Adhami
18990df41f
add capitalize and title var operations (#4840) 2025-02-18 12:45:43 -08:00
Khaleel Al-Adhami
3129ddab47
Add auto scroll (#4790)
* add auto_scroll

* add auto_scroll

* add auto_scroll to global

* use random id for maximum safety
2025-02-18 11:52:39 -08:00
Khaleel Al-Adhami
f4165c9812
fix types for html elements (#4768) 2025-02-18 10:20:22 -08:00
Masen Furer
6848915883
Update rx.get_upload_url signature to accept Var[str] (#4826)
* Update rx.get_upload_url signature to accept Var[str]

* Add py.typed

Fix #4806
2025-02-14 17:10:01 -08:00
Khaleel Al-Adhami
10bae9577c
only write if file changed (#4822)
* only write if file changed

* preface it on it existing
2025-02-13 22:49:27 -08:00
Khaleel Al-Adhami
7c4257a222
give option to only use main thread (#4809)
* give option to only use main thread

* change default to main thread

* fix comment

* default to None, as 0 would raise a ValueError

Co-authored-by: Masen Furer <m_github@0x26.net>

* add warning about passing 0

* move executor to config

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-02-13 18:36:30 -08:00
Khaleel Al-Adhami
8e579efe47
remove some benchmarks from CI (#4812) 2025-02-13 16:17:06 -08:00
Khaleel Al-Adhami
b44bbc81a0
import var perf improvements (#4813)
* import var perf improvements

* use tuples over iterator

* the only thing that matters

* maybe tuple map is faster than tuple list comprehension

* do it in one list comprehension
2025-02-13 15:54:10 -08:00
Khaleel Al-Adhami
aac61c69c2
actually get rid of callable var fr fr (#4821) 2025-02-13 15:40:01 -08:00
Khaleel Al-Adhami
6fb491471b
cache get_type_hints for environment (#4820) 2025-02-13 13:44:02 -08:00
Khaleel Al-Adhami
40294a7c9e
standarize filename from upload (#4734)
* standarize filename from upload

* all my friends hate fast api upload file

* make deprecated filename private

* lstrip the "/"

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-02-13 13:36:59 -08:00
Khaleel Al-Adhami
c6fb4e238d
improve into component conversion (#4754)
* improve into component conversion

* correct the order of .State
2025-02-13 12:44:42 -08:00
Khaleel Al-Adhami
10c45b185c
adjust setter to include type annotation (#4726)
* adjust setter to include type annotation

* apparently this discovered some bugs

* remove some pyright ignores

* add str to int/float conversion

* dang it darglint
2025-02-13 12:44:27 -08:00
Thomas Brandého
2ba73f7ff9
bump ruff to 0.9.6 (#4817) 2025-02-13 10:19:33 -08:00
Khaleel Al-Adhami
d79366d8b2
benchmark experimentation (#4811)
* benchmark experimentation

* do the same for test_evaluate_page

* import templates beforehands

* add auto reload

* disable extensions
2025-02-12 14:51:58 -08:00
Thomas Brandého
dd5b817f0f
fix port handling (#4773)
* handle port better

* setting port via envvar is possible again

* change default deploy_url and api_url

* fix for review

* update docstring

* type new envvar as optional
2025-02-12 19:06:01 +01:00
Khaleel Al-Adhami
977e1dcb67
update deps 2025-02-11 (#4804) 2025-02-12 09:05:36 -08:00
Thomas Brandého
a31301cb4f
add stateful benchmarks (#4764)
* add stateful benchmarks

* make stateful stuff more complex

* unpack tuple in itertag

* fix comment
2025-02-11 18:51:05 -08:00
Masen Furer
7da96a1175
pyproject.toml: bump to 0.7.1 for further development (#4808) 2025-02-11 18:41:04 -08:00
Masen Furer
3f68a27a22
[ENG-4647] Fix env_file handling (#4805)
* [ENG-4647] Fix env_file handling

* Import dotenv.load_dotenv early to avoid ImportError while loading
  rxconfig.py
* Read ENV_FILE from the environment explicitly.

fix #4803

* Config.Config: use_enum_values = False

Save enum fields as the enum object rather than the value.
2025-02-11 18:05:33 -08:00
Khaleel Al-Adhami
cb2e7df96a
invert logic of default hot reload exclusion (#4807)
* invert logic of default hot reload exclusion

* console debug reload paths
2025-02-11 17:47:44 -08:00
Khaleel Al-Adhami
6cbdd00169
fix toast provider needed (#4801)
* fix toast provider needed

* fix tests
2025-02-11 16:46:06 -08:00
Simon Young
289d10d30e
test actions in codeql (#4802) 2025-02-11 16:04:03 -08:00
Simon Young
e5e6c4e1d7
Create codeql.yml (#4799)
* Create codeql.yml

* add config

* fix that guy who's mad

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2025-02-11 15:49:06 -08:00
Declan Brady
894a01a5a5
Add toast.loading from the sonner package (#4792) 2025-02-11 12:21:27 -08:00
Thomas Brandého
64b1630d02
set global loglevel for subprocesses (#4791) 2025-02-11 12:15:38 -08:00
Khaleel Al-Adhami
372bd22475
raise error when passing a str(var) (#4769)
* raise error when passing a str(var)

* make it faster

* fix typo

* fix tests

* mocker consistency

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

* ditto

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

---------

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
2025-02-11 11:39:55 -08:00
Khaleel Al-Adhami
d545ee3f0b
move overlays to _app.js (#4794)
* move overlays to _app.js

* fix unit tests

* fix dynamic imports app

* fix unit cases once again

* clear custom compoent cache between app harness tests
2025-02-11 11:39:38 -08:00
Khaleel Al-Adhami
a194c90d6f
improve hot reload handling (#4795) 2025-02-11 11:39:28 -08:00
Khaleel Al-Adhami
90be664981
improve icon error message (#4796) 2025-02-11 11:39:14 -08:00
Masen Furer
85f07fcd89
Sticky tweaks: only show in prod mode (#4789)
* Sticky tweaks: only show in prod mode

Only display the sticky badge in prod mode.

Display the mini-badge for mobile and tablet; full badge only displayed at
desktop width.

* Remove localhost checking
2025-02-10 12:22:37 -08:00
Thomas Brandého
3a02d03cb1
fix bun path handling and add a test (#4785)
* fix bun path handling and add a test

* fix flags

* fix tests

* fix unit tests and mock object

* fix units test again

* revert some changes for now

* remove unused test
2025-02-10 11:44:44 -08:00
Masen Furer
8b2c7291d3
Add ComputedVar overloads for BASE_TYPE, SQLA_TYPE, and DATACLASS_TYPE (#4777)
Allow typing to find __getattr__ for rx.var that returns an object-like model.
2025-02-07 17:38:42 -08:00
Simon Young
3de04156e9
allow gunicorn worker to be disabled (#4774)
* allow gunicorn worker to be disabled

* allow gunicorn worker to be disabled

* rewrite the command

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2025-02-07 17:20:35 -08:00
Khaleel Al-Adhami
ee731a908d
provide plotly subpackages (#4776) 2025-02-07 17:19:28 -08:00
Masen Furer
70920a64be
Copy/update assets on compile (#4765)
* Add path_ops.update_directory_tree:

Copy missing and newer files from src to dest

* add console.timing context

Log debug messages with timing for different processes.

* Update assets tree as app._compile step.

If the assets change between hot reload, then update them before reloading (in
case a CSS file was added or something).

* Add timing for other app._compile events

* Only copy assets if assets exist

* Fix docstring for update_directory_tree
2025-02-07 14:59:22 -08:00
Masen Furer
c17cda3e95
Ensure EventCallback exposes EventActionsMixin properties (#4772) 2025-02-07 14:57:12 -08:00
Khaleel Al-Adhami
f3220470e8
fix dynamic icons for underscore and positional argument (#4767)
* fix dynamic icons for underscore and positional argument

* use no return
2025-02-07 14:20:29 -08:00
Khaleel Al-Adhami
b3b79a652d
improve foreach behavior with strings (#4751)
* improve foreach behavior with strings

* add a defensive guard before giving up

* add integration tests
2025-02-06 10:41:38 -08:00
Khaleel Al-Adhami
ab558ce172
increase nested type checking for component var types (#4756)
* increase nested type checking for component var types

* handle mapping as dict in type hint

* fix weird cases of using _isinstance instead of isinstance

* test out nested=0

* move union below

* don't use _instance for simple unions
2025-02-06 10:09:40 -08:00
Khaleel Al-Adhami
9d23271c14
improve behavior on missing language with markdown code blocks (#4750)
* improve behavior on missing language with markdown code blocks

* special case on literal var

* fix tests

* missing f

* remove extra throw
2025-02-06 10:09:26 -08:00
Khaleel Al-Adhami
1651289485
use getattr when given str in getitem (#4761)
* use getattr when given str in getitem

* stronger checking and tests

* switch ordering

* use safe issubclass

* calculate origin differently
2025-02-06 10:09:05 -08:00
Khaleel Al-Adhami
6f4d328cde
add a config variable to add extra overlay components (#4763)
* add a config variable to add extra overlay components

* add integration test

* Apply suggestions from code review

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-02-05 18:34:53 -08:00
Khaleel Al-Adhami
88eae92d9b
make computed var generic over mapping (#4762) 2025-02-05 16:16:30 -08:00
Masen Furer
49e48a5a8c
Resolve custom component version dynamically (#4759)
If the custom component is using setuptools_scm or some other dynamic
versioning scheme, use `build.util` to get the actual version being published.
2025-02-05 16:15:23 -08:00
Thomas Brandého
d0199a326f
move benchmarks and add some more (#4758)
* move benchmarks and add some more

* change key and paths

* parametrize tests

* more specific ignore

* rename fixture

* remove previous file

* add tests for _compile_stateful_components
2025-02-05 13:19:45 -08:00
Khaleel Al-Adhami
19f40745f8
remove base_state from event types (#4740)
* remove base_state from event types

* pyi that guy

* unpack is new

* woops

* use type alias type to remove ambiguity of where types go

* use same thing with LAMBDA_OR_STATE

* do it for event type
2025-02-05 12:09:15 -08:00
Carlos
d0ffc9b6ce
Update disabled backend component (#4747)
* Update disabled backend component

* fix test message

* it's ruff out there

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2025-02-05 10:35:48 -08:00
Khaleel Al-Adhami
88f9424df7
chmod rm when rm fails (#4755) 2025-02-05 10:25:47 -08:00
Thomas Brandého
59d8d1eb62
throw error if computed var has args (#4753)
* throw error if computed var has args

* change message
2025-02-05 09:23:41 -08:00
Khaleel Al-Adhami
af9a914ecc
move id to trigger instead of root (#4752) 2025-02-04 17:30:41 -08:00
Khaleel Al-Adhami
c3ac051bbb
don't memoize tooltip or skeleton children (#4744)
* don't memoize tooltip children

* Skip memoizing skeleton children

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-02-04 10:59:03 -08:00
PeterYusuke
2e9654725e
fix readme typo and update gallery to templates (#4745) 2025-02-04 16:27:14 +01:00
Masen Furer
20e8b83421
[ENG-4570] Fix rx.foreach over dict (#4743)
* Add test case for literal dict in foreach

* [ENG-4570] Iterate over ObjectVar.entries

* Adjust expectations of test_foreach.py unit tests
2025-02-03 17:21:00 -08:00
Masen Furer
2ff840aba6
Allow template with unspecified demo_url (#4741) 2025-02-03 16:28:36 -08:00
Thomas Brandého
44d6e1124c
fix bun message (#4739)
* fix bun message

* fix units tests mocking
2025-02-03 16:05:47 -08:00
Thomas Brandého
ef93161840
Add a sticky Built with Reflex badge (#4584)
* add the watermark class

* remove shortcut exposing badge publicly for now

* Rename as "sticky" because "watermark" has a negative connotation

* Add config `show_built_with_reflex`

This config option is available for authenticated users on various plan tiers

* py3.11 compatible f-string

* sticky badge inherit from A instead of using on_click/redirect

* fix integration test

* Move export checking logic to reflex CLI

* rx.logo: make it accessible to screen readers

Add role="img" aria_label="Reflex" and title="Reflex".

* Hide the built with reflex badge for localhost

* Revert "fix integration test"

This reverts commit a978684d70.

* experimental: do not show warning for internal imports

Only show experimental feature warnings when accessing the names through the
rx._x namespace.

If reflex internally imports the names via deep imports, then this bypasses the
warning to avoid showing it to users that have no control over how the
framework uses experimental features.

* add help link for show_built_with_reflex option

* pre-commit fixes

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-02-03 11:50:31 -08:00
benedikt-bartscher
73ef17b96d
fix: allow replacing of _var_type in ComputedVar (worked in previous reflex versions) (#4730) 2025-02-03 10:16:01 -08:00
benedikt-bartscher
d6e08e90a8
better computed var static deps (#4729)
* better computed var static deps

* typing and usability improvements for computed var static dependencies
2025-02-03 09:34:12 -08:00
benedikt-bartscher
2b7e4d6b4e
improve rx.Field ObjectVar typing for sqlalchemy and dataclasses (#4728)
* improve rx.Field ObjectVar typing for sqlalchemy and dataclasses

* enable parametrized objectvar tests for sqlamodel and dataclass

* improve typing for ObjectVars in ArrayVars

* ruffing

* drop duplicate objectvar import

* remove redundant overload

* allow optional hints in rx.Field annotations to resolve to the correct var type
2025-02-03 09:33:22 -08:00
Khaleel Al-Adhami
15da4e17bd
fix optional wrapping of static call methods in pyi (#4727) 2025-02-03 09:31:32 -08:00
Alek Petuskey
68547dce4c
Remove upper pin (#4684)
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2025-01-31 19:22:00 -08:00
Khaleel Al-Adhami
238b03a8c7
disable react strict mode for event loop (#4720)
* disable react strict mode for event loop

* oops

* pyi oui

* separate socket connection from event loop

* prettier state.js

* disable react strict mode

* didn't work sadge

* socket connect/disconnect depends on new isBackendDisabled state

* only start the event loop when the socket is set or we're not stateful

* Always drain the queue unless backend is disabled

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-01-31 18:36:35 -08:00
Thomas Brandého
83e635de0e
bump ruff version to 0.9.3 (#4705)
* bump ruff version to 0.9.3

* relock poetry file

* poetry relock

* ignore RUF008 for now

* pass pre-commit

* update-pyi-files: require_serial to avoid mp explosion

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-01-31 17:20:51 -08:00
Khaleel Al-Adhami
3cb4443128
add evaluate time to the progress counter (#4722) 2025-01-31 16:43:05 -08:00
Khaleel Al-Adhami
80a26b440d
include dynamic imports for custom components (#4725) 2025-01-31 16:42:55 -08:00
Masen Furer
a2243190ff
[ENG-4326] Async ComputedVar (#4711)
* WiP

* Save the var from get_var_name

* flatten StateManagerRedis.get_state algorithm

simplify fetching of states and avoid repeatedly fetching the same state

* Get all the states in a single redis round-trip

* update docstrings in StateManagerRedis

* Move computed var dep tracking to separate module

* Fix pre-commit issues

* ComputedVar.add_dependency: explicitly dependency declaration

Allow var dependencies to be added at runtime, for example, when defining a
ComponentState that depends on vars that cannot be known statically.

Fix more pyright issues.

* Fix/ignore more pyright issues from recent merge

* handle cleaning out _potentially_dirty_states on reload

* ignore accessed attributes missing on state class

these might be added dynamically later in which case we recompute the
dependency tracking dicts... if not, they'll blow up anyway at runtime.

* fix playwright tests, which insist on running an asyncio loop

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2025-01-31 16:33:30 -08:00
Khaleel Al-Adhami
7da5fa0e5c
implement a global var cache (#4691)
* implement a global var cache

* fix misisng types

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-01-31 14:28:04 -08:00
Khaleel Al-Adhami
8663dbcb97
improve var base typing (#4718)
* improve var base typing

* fix pyi

* dang it darglint

* drain _process in tests

* fixes #4576

* dang it darglint
2025-01-31 13:12:33 -08:00
Khaleel Al-Adhami
12a42b6c47
var_data fixes with hooks values (#4717)
* var_data fixes with hooks values

* remove the raise error
2025-01-31 13:07:51 -08:00
Khaleel Al-Adhami
335816cbf7
add backend disabled dialog (#4715)
* add backend disabled dialog

* pyi that guy

* pyi the other guy

* extend test_connection_banner to also test the cloud banner

* oops, need asyncio _inside_ the app

* Update reflex/components/core/banner.py

Co-authored-by: Masen Furer <m_github@0x26.net>

* use universal cookies

* fix pre-commit

* revert universal cookie 🍪

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-01-31 13:00:56 -08:00
Khaleel Al-Adhami
6231f82248
add codspeed (#4707)
* add codspeed

* add codspeed to dev deps

* poetry.lock: relock deps, no update

* add poetry run

* only compile components

* at least have something

* fix hash

* dang it darglint

* uwu

* test sorting algorithms

* test sort

* sad

* revert that guy

* add test_evaluate

* it's ruff out there

* delete test_sort

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-01-31 11:39:19 -08:00
Masen Furer
fc16bed7ca
Handle python range passed to rx.Var.create (#4716)
* Handle python `range` passed to rx.Var.create

Fix the range function to use Math.ceil to handle jagged steps.

Update test cases.

* Set ToVarOperation.__qualname__ for better repr
2025-01-31 11:21:51 -08:00
Thomas Brandého
87d93b33b8
followup for merge style PR (#4721) 2025-01-31 11:17:46 -08:00
Khaleel Al-Adhami
12bda1d4f5
make all triggers disable recurisve memoization (#4719) 2025-01-31 11:15:42 -08:00
Khaleel Al-Adhami
2c3257d4ea
fix tag render to be recursive (#4714) 2025-01-29 12:16:54 -08:00
Khaleel Al-Adhami
1e8e82ec0e
allow functools partial with foreach (#4709) 2025-01-28 23:03:22 -08:00
Khaleel Al-Adhami
58e63f387f
assert that .render returns jsonable values (#4708)
* assert that .render returns jsonable values

* render component default
2025-01-28 23:02:14 -08:00
Khaleel Al-Adhami
5beea25b31
improve var create typing (#4701) 2025-01-28 22:56:38 -08:00
Thomas Brandého
58f87a6aa7
only allow item inside root (#4697) 2025-01-28 22:54:23 -08:00
Thomas Brandého
96ead07606
fix padding style in textarea (#4696) 2025-01-28 22:53:40 -08:00
Thomas Brandého
b8b3f8910e
add more type annotations through the code (#4401)
* add more type annotations through the code

* add typing in reflex/utils

* misc typing

* more typings

* state typing

* keep typing

* typing init and utils

* more typing for components

* fix attempt for 3.9

* need more __future

* more typings

* type event plz

* type model

* type vars/base.py

* enable 'ANN001' for reflex folder (ignore tests and benchmarks)

* fix pyi

* add missing annotations

* use more precise error when ignoring
2025-01-29 01:12:47 +01:00
Khaleel Al-Adhami
2a922214a2
improve error message for failed compile_state (#4702) 2025-01-28 16:07:53 -08:00
Thomas Brandého
3bd2bea54d
merging two style instance should give a style instance (#4706)
* merging two style instance should give a style instance

* fix ci

* carry _var_data
2025-01-28 22:47:57 +01:00
Thomas Brandého
42e6dfa40d
enable PGH, bump pyright and fix all #type: ignore (#4699)
* enable PGH, bump pyright and fix  all #type: ignore

* relock poetry file

* ignore incompatible override

* fix varop tests

* ignore missing imports

* fix

* fix stuff

* fix tests

* rechange tests

* relock with poetry 2.0
2025-01-28 13:11:05 -08:00
Khaleel Al-Adhami
64fb78ac5e
fix subprotocol for granian (#4698)
* fix subprotocol for granian

* use scope subprotocols

* use subprotocols or headers

* separate the logic
2025-01-28 11:46:00 -08:00
Thomas Brandého
9e36efbd21
fix version in pyproject and ruff version check (#4690)
* fix version in pyproject and ruff version check

* relock deps

* relax some strict values
2025-01-28 14:20:26 +01:00
Khaleel Al-Adhami
4d08484a12
import vars are not sortable (#4700) 2025-01-27 21:31:14 -08:00
Thomas Brandého
61a6ab9bbd
fix stuff with bun_path (#4688)
* fix stuff with bun_path

* which always return Path object

* try using samefile() for file path comparison

* check for None

* fix tests, maybe

* fix more tests
2025-01-27 12:37:00 -08:00
Khaleel Al-Adhami
709c6dedf2
[ENG-4444] move states out of .web (#4689)
* move states out of .web

* create file parents if they don't exist
2025-01-24 12:38:14 -08:00
Khaleel Al-Adhami
abc9038580
return websocket protocol when asked (#4683) 2025-01-23 15:10:07 -08:00
Khaleel Al-Adhami
9dba8cd494
use older version of python for windows simple benchmarks (#4680) 2025-01-23 15:29:31 +01:00
Thomas Brandého
7f1aee6dc8
enable N rules for naming conventions (#4666)
* enable N rules for naming conventions

* fix pyi

* address comments

* remove unneeded code
2025-01-23 15:29:17 +01:00
Thomas Brandého
858a85a4dc
rename private fields with leading underscore in App (#4642)
* rename private fields with leading underscore in App

* fix constants API

* fix public API for some attributes of App()

* fix conflicts properly 🙈

* remove extra private

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2025-01-23 15:28:56 +01:00
Ahmad Hakim
c58db4d005
pie chart type annotation fix (#4681)
Co-authored-by: pourhakimi <84860195+pourhakimi@users.noreply.github.com>
2025-01-23 15:52:25 +02:00
Khaleel Al-Adhami
3aaa26c82f
attempt to upgrade windows latest python version (#4679)
* attempt to upgrade windows latest python version

* remove that silly one
2025-01-22 17:56:41 -08:00
Masen Furer
6d314d10c5
Fix setting default color mode in dev mode (#4616)
* Fix setting default color mode in dev mode

Without this, the last_compiled_timestamp local storage never gets set because
it's always `null` until it gets set.

* test_client_storage: also pop `theme` key from next-themes
2025-01-22 15:30:11 -08:00
Elijah Ahianyo
1ca36fa6c1
[ENG-1796]reflex rename- B (#4668)
* `reflex rename`- B

* add unit tests

* precommit

* dont need this comment

* move loglevel

* calm down, darglint

* add current dir to sys path
2025-01-22 15:26:12 -08:00
Masen Furer
818788da63
Do not track compile in posthog metrics (#4669) 2025-01-22 15:23:34 -08:00
Khaleel Al-Adhami
0139cab13f
refactor client state to restore prior API (#4674)
* refactor client state to restore prior API

* maybe add that
2025-01-22 15:23:06 -08:00
Khaleel Al-Adhami
8dea682781
update bun to 1.2.0 (#4678) 2025-01-22 15:19:25 -08:00
Khaleel Al-Adhami
1106aae76e
remove integration screenshots (#4677) 2025-01-22 15:18:35 -08:00
Masen Furer
109b272bc2
Bump frontend and backend deps (#4667)
* relock backend deps

* bump frontend library versions

* go back to react 18.3

* revert to react 18.3.1 (as it was before)

* reflex-web keep reflex from current revision, rather than main

* relock backend deps (again)

* don't check ag-grid version on main repo

* config_path is passed via `extra` to avoid pyright error when None

* bump next again

---------

Co-authored-by: Lendemor <thomas.brandeho@gmail.com>
2025-01-22 15:18:05 -08:00
Thomas Brandého
4c2b2ed1c6
removing deprecated features for 0.7.0 and removing py3.9 support (#4586)
* remove deprecated features and support for py3.9

* remove other deprecated stuff

* update lock file

* fix units tests

* relock poetry

* fix _replace for computed_var

* fix some merge typo

* fix typing of deploy args

* fix benchmarks.yml versions

* console.error instead of raising Exception

* fix tests

* ignore lambdas when resolving annotations

* simplify redirect logic in event.py

* more fixes

* fix unit tests again

* give back default annotations for lambdas

* fix signature check for on_submit

* remove useless stuff

* update pyi

* readd the getattr

* raise if log_level is wrong type

* silly goose, loglevel is a subclass of str

* i don't believe this code

* add guard

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2025-01-22 11:54:37 -08:00
Khaleel Al-Adhami
db13fe65b8
reflex export environment should default to prod (#4673)
* reflex export environment should default to prod

* what

* wat

* what is this silly goose
2025-01-22 11:11:47 -08:00
Khaleel Al-Adhami
8de14d4384
Fix recharts min width/height (#4672) 2025-01-22 11:11:25 -08:00
Thomas Brandého
728607643f
attempt to fix usage when volta is installing node (#4664)
* attempt to fix usage when volta is installing node

* use absolute() instead of resolve()

* fix stuff
2025-01-22 16:58:33 +01:00
Khaleel Al-Adhami
a923f657ac
retry failed tests (#4675)
* retry failed tests

* retry even more
2025-01-22 16:27:17 +01:00
Ahmad Hakim
80966dbff0
[ENG-4406] cell component wrapper (#4670)
* cell component wrapper

* add pyi files changes

---------

Co-authored-by: pourhakimi <84860195+pourhakimi@users.noreply.github.com>
Co-authored-by: Lendemor <thomas.brandeho@gmail.com>
2025-01-22 09:00:43 +02:00
Elijah Ahianyo
048416163d
Remove token check in reflex deploy (#4640)
This logic has been moved upstream to reflex-hosting-cli
2025-01-21 13:28:05 -08:00
Khaleel Al-Adhami
bea266b8ed
make object var handle all mapping instead of just dict (#4602)
* make object var handle all mapping instead of just dict

* unbreak ci

* get it right pyright

* create generic variable for field

* add support for typeddict (to some degree)

* import from extensions
2025-01-21 13:14:02 -08:00
Elijah Ahianyo
abaaa22adb
Allow deploy with project name and app id (#4550)
* `reflex deploy --project-name`

* add app id as well

* config file update

* Update reflex/reflex.py

Co-authored-by: Masen Furer <m_github@0x26.net>

* Update reflex/reflex.py

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: simon <simon@reflex.dev>
Co-authored-by: Masen Furer <m_github@0x26.net>
2025-01-21 13:06:12 -08:00
Khaleel Al-Adhami
0c70146013
check frontend version on connect (#4611)
* check frontend version on connect

* do something a bit silly

* thanks masen

* just delete the tests you don't pass
2025-01-21 13:05:35 -08:00
Masen Furer
212b2d4af9
Skip saving page components when skipping compile output (#4653)
Obviously we still have to evaluate the pages to make sure we know about all
states, but not saving them to `App.pages` dict reduces high-line memory usage
for backend-only process from ~900Mb to ~530Mb on reflex-web.
2025-01-21 13:05:04 -08:00
Khaleel Al-Adhami
4dc106545b
add defensive checks against data being funny (#4633) 2025-01-20 14:00:08 -08:00
Thomas Brandého
2855ed4887
add some of the TRY rules (#4651) 2025-01-20 13:58:17 -08:00
Thomas Brandého
9c019a65d5
check for dict passed as children for component (#4656) 2025-01-20 13:55:53 -08:00
Elijah Ahianyo
268effe62e
[ENG-4134]Allow specifying custom app module in rxconfig (#4556)
* Allow custom app module in rxconfig

* what was that pyscopg mess?

* fix another mess

* get this working with relative imports and hot reload

* typing to named tuple

* minor refactor

* revert redis knobs positions

* fix pyright except 1

* fix pyright hopefully

* use the resolved module path

* testing workflow

* move nba-proxy job to counter job

* just cast the type

* fix tests for python 3.9

* darglint

* CR Suggestions for #4556 (#4644)

* reload_dirs: search up from app_module for last directory containing __init__

* Change custom app_module to use an import string

* preserve sys.path entries added while loading rxconfig.py

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2025-01-20 10:12:54 -08:00
Thomas Brandého
4da32a122b
allow dynamic icons name (#4636)
* allow dynamic icons name

* handle literal vars

* clean up code
2025-01-17 16:43:11 -08:00
Thomas Brandého
6e546526b4
computed var default to cache=True (#4194)
* computed var default to cache=True

* fix lifespan integration tests

* fix redis test
2025-01-16 21:49:54 +01:00
Khaleel Al-Adhami
c8de356d98
cast return_expr to Var all the time (#4649) 2025-01-16 20:22:56 +01:00
Thomas Brandého
e8dd0ae47d
don't need node when --backend_only is used (#4641) 2025-01-15 15:57:50 -08:00
Khaleel Al-Adhami
cb24492371
fix boolean to boolen comparisons (#4620)
* fix boolean to boolen comparisons

* fixes #4618

* fix tests
2025-01-15 14:23:45 -08:00
Khaleel Al-Adhami
b50b7692b2
improve type support for .get_state (#4623)
* improve type support for .get_state

* dang it darglint
2025-01-15 14:21:33 -08:00
Thomas Brandého
9fe8e6f1ce
bump nextJS to v15 (#4630)
* bump nextJS to v15

* make turbopack depends on env var
2025-01-15 14:20:04 -08:00
Masen Furer
fbf9524a6c
Show file and line number in deprecation warnings (#4631)
* Show file and line number in deprecation warnings

* Exclude modules/packages by import

Less bespoke method of considering some packages to be part of the framework
and passed over when finding user code.
2025-01-15 14:19:11 -08:00
Khaleel Al-Adhami
caf29c3680
put import at the top of dynamic component evaluation (#4632) 2025-01-15 14:17:58 -08:00
Masen Furer
e8a7112249
[ENG-4383] Handle special float values on frontend (#4638)
Add a test case to `test_computed_vars.py` which renders a list of special floats.

Fix #4637
2025-01-15 13:04:15 -08:00
Thomas Brandého
f69be58f59
small fix for color_mode_button (#4634) 2025-01-14 15:02:54 +01:00
Masen Furer
1e7a37bcf9
[ENG-4351] Add mapping for lucide icons (#4622)
* [ENG-4351] Add mapping for lucide icons

For icon names that don't auto-translate to the correct lucide tag name,
provide manual override.

Fix #4621

* account for new mapping in unit tests
2025-01-10 15:23:16 -08:00
Masen Furer
427d7c56ab
Revert "[ENG-4005] Proxy backend requests on '/' to the frontend (#3300)" (#4614)
This reverts commit 438b31f270.
2025-01-09 16:30:49 -08:00
Masen Furer
fe9c02062d
EventChain.create accepts arbitrary kwargs (#4609)
Pass _var_data when creating LiteralVar

Partial fixes for #4608
2025-01-09 16:14:38 -08:00
Khaleel Al-Adhami
79611abdab
make that one line better (#4610) 2025-01-08 17:16:38 -08:00
Masen Furer
4c97072a3c
pyproject.toml: bump to 0.7.0dev1 for further development (#4604) 2025-01-08 09:37:33 -08:00
Masen Furer
5d877d54d0
Use older python versions for macos actions (#4601)
Use python versions that have a darwin/arm64 build for use with the newer
(faster) macos actions runners
2025-01-07 15:46:26 -08:00
Khaleel Al-Adhami
0ad0a84ee1
fix recursive UI (#4599)
* fix recursive UI

* get it right pyright

* dang it darglint
2025-01-07 15:11:38 -08:00
Khaleel Al-Adhami
880975ae94
improve client state (#4597)
* improve client state

* no comma

* update python for unit tests

* overwrite it for windows

* bump other python versions
2025-01-07 14:41:03 -08:00
Masen Furer
93245ef143
[ENG-4255] Code blocks lead to redefined const in web page (#4598)
Instead of potentially defining `_LANGUAGE` constant twice in a component,
simply pass the language prop directly to the hook generator function.

If no language is passed, then it defaults to `_LANGUAGE`, which continues to
work for markdown component_map use case.
2025-01-07 13:20:25 -08:00
Masen Furer
5f169bc884
test_lifespan: stop periodic events (#4600)
avoid lingering events after getting the information we came for
2025-01-07 13:20:10 -08:00
Masen Furer
08d9fbf9bc
unbreak link _hover (#4537)
* unbreak link _hover

* add a test to catch the error

* change tmp path for harness

* add () to fixture

* add spacer to avoid initial hover

* only install chromium browser for faster ci

---------

Co-authored-by: Lendemor <thomas.brandeho@gmail.com>
2025-01-07 10:35:36 -08:00
Masen Furer
72d7616726
Enable automatic retry on redis errors (#4595)
* Enable automatic retry on redis errors

ExponentialBackoff 3x retry for BusyLoadingError, ConnectionError, and TimeoutError

* retry on any redis error

* Use default single-retry for any RedisError

Using the default Retry means that async and sync clients get the appropriate type of Retry
2025-01-07 10:24:43 -08:00
Masen Furer
eae15e3a83
poetry 2.0.0 compatibility (#4593)
Remove `packages` key, since this project uses the "default" package layout, so
this key isn't needed.
2025-01-06 14:35:45 -08:00
Thomas Brandého
9fafb6d526
use position in vardata to mark internal hooks (#4549)
* use position in vardata to mark internal hooks

* update all render to use position

* use macros for rendering

* reduce number of iterations over hooks during rendering

* cleanup code and add typing

* add __future__

* use new macros to render component maps in markdown

* remove calls to _get_all_hooks_internal

* fix typo

* forgot to replace this

* unnecessary expand in utils.py
2025-01-06 13:06:56 -08:00
Masen Furer
59b3aaca42
Add deprecation message for non-cached var (#4591)
DeprecationWarning: Default non-cached rx.var has been deprecated in version
0.6.8 the default value will be `@rx.var(cache=True)` in a future release. To
retain uncached var, explicitly pass `@rx.var(cache=False)`. It will be
completely removed in 0.7.0
2025-01-06 11:17:03 -08:00
Kanva Bhatia
ab4e05be34
fixes #4578 - correct the way dim_props created (#4587) 2025-01-05 14:53:39 -08:00
Masen Furer
dcdcbfd833
[ENG-2157] [Refix] Allow rx.download to resolve rx.get_upload_url (#4470)
* [ENG-2157] [Refix] Allow `rx.download` to resolve `rx.get_upload_url`

Update the special case in a way that works with the new Var system and its
unstoppable determination to concatenate strings instead of using template
string

This has been broken since 0.6.0, so a regression test was added to avoid
future inadvertant breakage.

Fix #2812 (again)

* use safer indirect eval
2025-01-03 16:56:29 -08:00
Masen Furer
438b31f270
[ENG-4005] Proxy backend requests on '/' to the frontend (#3300)
* Proxy backend requests on '/' to the frontend

If the optional extra `proxy` is installed, then the backend can handle all
requests by proxy unrecognized routes to the frontend nextjs server.

* Update lock file

* pre-commit fu

* AppHarness: set config frontend_port and backend_port

* integration: frontend port and backend port should return the same content

with proxying enabled by default in dev mode, both frontend and backend ports
on / should return the same content.

* Retry up to 100 times when proxying to frontend

* Reduce retry attempts to 25

Fix log level passing to subprocess

* scripts/wait_for_listening_port: primarily check HTTP responses

if the port is up or not, we don't really care... the HTTP request needs to
work and not return errors

* aiohttp is an optional dep

* adapt integration.sh for --backend-only (counter integration test)

* woops

* windows WTF?

* scratching my head 🎄

* double WTF windows

* Fix remaining integration tests
2025-01-03 15:50:38 -08:00
Masen Furer
316a0c9bde
Do not allow call_function callback argument to be added afterwards (#4552)
The default behavior for EventSpec is to treat the spec as a partial, wherein
if additional unfilled arguments are available, and the event trigger wants to
pass additional arguments, they will be applied positionally.

However, it never makes sense to fill in `callback` with an event trigger arg.
Therefore, if the callback is not provided initially, set it to None explicitly
so that some invalid value cannot be added later.
2025-01-03 15:50:01 -08:00
Masen Furer
8477a1aba0
BaseState.get_var_value helper to get a value from a Var (#4553)
* BaseState.get_var_value helper to get a value from a Var

When given a state Var or a LiteralVar, retrieve the actual value associated
with the Var.

For state Vars, the returned value is directly tied to the associated state and
can be modified.

Modifying LiteralVar values or ComputedVar values will have no useful effect.

* Use Var[VAR_TYPE] annotation to take advantage of generics

This requires rx.Field to pass typing where used.

* Add case where get_var_value gets something that's not a var
2025-01-03 15:49:46 -08:00
Masen Furer
41cb2d8cff
[ENG-4083] Track internal changes in dataclass instances (#4558)
* [ENG-4083] Track internal changes in dataclass instances

Create a dynamic subclass of MutableProxy with `__dataclass_fields__` set
according to the dataclass being wrapped.

* support dataclasses.asdict on MutableProxy instances
2025-01-03 15:49:28 -08:00
Simon Young
4b89b8260b
HOS-400: adding support for config (#4540)
* HOS-400: adding support for config

* ruff

---------

Co-authored-by: simon <simon@reflex.dev>
2025-01-03 15:15:13 -08:00
benedikt-bartscher
879dcbd1bf
improve dynamic route vars, no need to compute deps (#4551) 2025-01-03 13:00:48 -08:00
celsius narhwal
0d9b2c75e4
Upgrade lucide-react to version 0.469.0 (#4571) 2025-01-03 12:59:05 -08:00
JonZeolla
72a60f074b
chore: update sonner (toast) (#4572) 2025-01-03 12:55:51 -08:00
Thomas Brandého
53f09756b6
autodetect print/breakpoints (#4581)
* catch stray breakpoints and prints

* autodetect debug prints and breakpoints in main code

* readd hacky print in pyi_generator?
2025-01-03 12:51:02 -08:00
Ryan
97fb157b25
Add endswith method to String class (#4577)
Co-authored-by: ryan <>
2025-01-03 12:50:04 -08:00
Masen Furer
12eaf08c88
Add expire_on_commit=False for async sessions (#4582) 2025-01-02 14:15:59 -08:00
Masen Furer
41ed9f0514
Move _create_event_chain to EventChain.create (#4557)
The ability to convert `EventType` arguments into `EventChain` is crucial for
wrapping JS libraries that need to pass event handlers via hooks or
other non-component centric interfaces.

Improve typing such that wrapped components accepting `EventType` arguments can
be directly converted to `EventChain` / `EventChainVar` to be rendered as JS
code.
2025-01-02 14:15:38 -08:00
Thomas Brandého
848b87070c
fix health check and skip not needed tasks (#4563) 2024-12-20 17:08:10 -08:00
Thomas Brandého
a2ec1bc1d8
add codespell to pre-commit (#4559) 2024-12-20 17:04:39 -08:00
benedikt-bartscher
c310c020bb
Minor performance improvements for state getattribute and setattr (#4543) 2024-12-20 16:27:07 -08:00
Masen Furer
28568fd12f
Suppress exceptions from telemetry send (#4564) 2024-12-19 16:20:09 -08:00
Masen Furer
d8e988105f
pyproject.toml: bump to 0.6.8dev1 for further development (#4539) 2024-12-17 19:52:37 +01:00
Masen Furer
f71e6f9559
Revert "only mark backend vars as dirty if they have changed (#4494)" (#4547)
This reverts commit 3d89d74bdc.
2024-12-16 12:21:32 -08:00
Thomas Brandého
d7956c19d3
enable PERF rules (#4469)
* enable PERF rules

* fix scripts folder

* Update reflex/compiler/utils.py

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-12-13 14:49:37 -08:00
Thomas Brandého
61cb72596e
enable PTH rule (#4476)
* enable PTH rule

* fix import in test_call_script

* fix units tests

* reorder ruff rules

* Update reflex/utils/build.py

Co-authored-by: Masen Furer <m_github@0x26.net>

* format pyproject.toml

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-12-13 14:06:26 -08:00
Thomas Brandého
1444421766
add deps and position field in VarData (#4518)
* fix memoized event trigger order

* allow to declare deps in event signature for memoized event triggers

* clean up the code to pass tests

* handle position of hooks

* clean up code

* revert test changes

* add future annotations

* remove non-necessary stuff

* reuse data_callback name if already set during first call to add_hooks

* remove HookVar and use Var with VarData instead

* remove test change

* readd removed line

* fix order of stmt for cleaner code

* fix typing

* something broke during the merge I guess

* remove hack and pass proper const for position

* oops, bad syntax in jinja

* use "hook_position" instead of "hook_positions"

match the name of the enum

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-12-13 13:28:55 -08:00
Thomas Brandého
76ce112002
add datetime var comparison operations (#4406)
* add datetime var operations

* add future annotations

* add LiteralDatetimeVar

* remove methods that don't apply

* fix serialization

* add unit and integrations test

* oops, forgot to commit that important change
2024-12-13 12:41:29 -08:00
benedikt-bartscher
682bca7f9a
improve StateManagerRedis error message (#4444) 2024-12-13 12:40:38 -08:00
Thomas Brandého
ff510cacc5
enable C4 rule (#4536) 2024-12-13 12:37:34 -08:00
Joodith
ec89702137
Include step attribute in input (#4073)
* Include step attribute in input

* Remove `step` prop from TextField

it is inherited from Input, and does not need to be redefined

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-12-13 11:35:35 -08:00
Elijah Ahianyo
206de4df7a
Unify is_external prop in rx.redirect and rx.link (#4389)
* Unify `is_external` prop in `rx.redirect` and `rx.link`

* default external to `None`

* address PR comment

* use a one-liner

* reorder args for api stability

Co-authored-by: Masen Furer <m_github@0x26.net>

* reorder doc args

* external arg as deprecated in the docs

* Update reflex/event.py

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>

* Fixup typing_extensions import and ruff

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-12-13 11:27:51 -08:00
Masen Furer
f4aea1b3ab
[ENG-3583] Respect cors_allowed_origins for backend HTTP requests (#4533) 2024-12-13 09:31:27 -08:00
Vy Nguyen
7208540855
Wrap Checkbox component in Context Menu (partial fix for #4262) (#4479)
* Add ContextMenuCheckBoxItem component

* Remove toggle_state method

* Import Checkbox and implement ContextMenuCheckbox class

* Change parameter for create function

* Reformat code and import block

* Removed unused vars

* Format file

* Remove create method

* Reformat code

* Update reflex/components/radix/themes/components/context_menu.py

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

* Update reflex/components/radix/themes/components/context_menu.py

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

* Update reflex/components/radix/themes/components/context_menu.py

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

* Update reflex/components/radix/themes/components/context_menu.py

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

* Reformat code

* Add automatically modified pyi file

* Update context_menu.pyi file

---------

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
2024-12-13 01:50:01 +01:00
Elijah Ahianyo
7ca50c62e2
[ENG-4153]Use empty string for None values in rx.input and rx.el.input (#4521)
* Use empty string for None values in `rx.input` and `rx.el.input`

* fix tests

* fix pyi scripts

* use nullish coalescing operator

* fix unit tests

* use ternary operator so old browsers and dynamic components tests pass

* address comment on doing this only for optionals

* Fix tests

* pyright!

* fix comments
2024-12-12 15:24:15 -08:00
Masen Furer
d5d41a0d9e
raise_console_error during integration tests (#4535) 2024-12-12 14:28:30 -08:00
Masen Furer
60a5b7bc7a
[ENG-4194] TypeError: Cannot create property 'token' on string (#4534) 2024-12-12 14:28:17 -08:00
Elijah Ahianyo
c387f517b6
[ENG-4100]Throw warnings when Redis lock is held for more than the allowed threshold (#4522)
* Throw warnings when Redis lock is held for more than the allowed threshold

* initial tests

* fix tests and address comments

* fix tests fr, and use pydantic validators

* darglint fix

* increase lock expiration in tests to 2500

* remove print statement

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-12-12 11:36:31 -08:00
Masen Furer
2d9849e00a
Fix upload cancellation (#4527)
* Improve assertions in test_cancel_upload

* Fix upload cancellation by using `refs` instead of `upload_controllers`
2024-12-12 10:15:19 -08:00
Masen Furer
adfda8adfd
[ENG-4165] Consider default and default_factory for state vars (#4510)
* [ENG-4165] Consider default and default_factory for state vars

When determining whether a state var should be marked as optional, check that
it is missing both default and default_factory and is not required.

Fix #4471

* add test for default factory with rx.foreach (#4515)

---------

Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
2024-12-12 10:10:44 -08:00
benedikt-bartscher
1b6f539657
simplify redis code, less redis calls (#4456)
* simplify redis code, less redis calls

* cleanup

* properly ignore non-lock events from redis pubsub, keep timeout
2024-12-12 05:56:42 -08:00
Masen Furer
a2f14e7713
Avoid double JSON encode/decode for socket.io (#4449)
* Avoid double JSON encode/decode for socket.io

socket.io (python and js) already has a built in mechanism for JSON encoding
and decoding messages over the websocket. To use it, we pass a custom `json`
namespace which uses `format.json_dumps` (leveraging reflex serializers) to encode the
messages. This avoids sending a JSON-encoded string of JSON over the wire, and
reduces the number of serialization/deserialization passes over the message
data.

The side benefit is that debugging websocket messages in browser tools displays
the parsed JSON hierarchy and is much easier to work with.

* JSON5.parse in on_upload_progress handler responses
2024-12-12 05:47:23 -08:00
Masen Furer
053cbe7558
bump CI runners to macos-latest (#4526)
* use `macos-latest` runner

macos-12 is deprecated and the jobs don't start anymore, so see if we can run
fine on latest.

* unit_tests.yml: use python versions with arm64 builds
2024-12-12 04:17:28 -08:00
benedikt-bartscher
ea90a3ebfa
minor pickle improvement (#4499) 2024-12-12 02:07:59 -08:00
Thomas Brandého
5e026e4b27
Support python 3.13 (#4206)
* bump playwright and run tests with 3.13

* test with psycopg3

* typo

* update everything for psycopg 3.
2024-12-12 00:10:51 -08:00
Thomas Brandého
a86d2c612a
deprecate add_custom_404_page (#4505)
* deprecate add_custom_404_page

* show raw value in deprecate message

* fix typo

* Update reflex/app.py

Co-authored-by: Masen Furer <m_github@0x26.net>

* change removal version to 0.8.0

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-12-11 18:29:39 -08:00
benedikt-bartscher
a7151cd6c8
disable polling (#4441) 2024-12-11 18:29:01 -08:00
Thomas Brandého
fb444ad112
add ERA rules to detect commented out code (#4472)
* add eradicate rules for commented out code

* remove output change

* fix pyi messed up indent

* fix pyi again

* fix layout docstring

* fix pyi_generator to remove commented out props from docs

* fix pyi_generator and regenerate some pyi

* fix double strip

* update all pyi

* try to fix stuff in pyi_gen

* whatever

* remove that maybe? i don't know

* fix that shit?

* fix more shit, idk

* better not see you ever again, extra line
2024-12-11 18:26:44 -08:00
benedikt-bartscher
e4b5755568
fix: handle default_factory in get_attribute_access_type (#4517)
* fix: handle default_factory in get_attribute_access_type, add tests for sqla dataclasses

* only test classes which have default_factory + add test for no default
2024-12-11 18:22:31 -08:00
Masen Furer
95eb663347
client_state: create Var from value when pushing from backend (#4474)
This ensures that the value is properly escaped/formatted for direct use in
javascript code.
2024-12-11 17:15:17 -08:00
Masen Furer
d75a708e6b
Fix REFLEX_COMPILE_PROCESSES=0 (#4523)
when zero is passed, that is short for "use the default", which is actually
None in the code.

fix for both processes and threads being set to zero
2024-12-11 21:29:33 +01:00
benedikt-bartscher
2ee201b520
raise StateSerializationError if the state cannot be serialized (#4453)
* raise StateSerializationError if the state cannot be serialized

* fix test
2024-12-11 20:08:18 +01:00
Thomas Brandého
862d7ec807
add test for color mode (initial and toggle) (#4467)
* add test for color mode (initial and toggle)

* add css check

* add page reload in the tests

* update test to catch the appearance regression

* don't render the appearance prop of rx.theme
2024-12-11 19:57:51 +01:00
benedikt-bartscher
06d743cda9
fix: migrate is_backend_only (deprecated) to EnvironmentVariables (#4495) 2024-12-11 19:22:44 +01:00
Masen Furer
4922f7ba05
Reuse the sqlalchemy engine once it's created (#4493)
* Reuse the sqlalchemy engine once it's created

* Implement `rx.asession` for async database support

Requires setting `async_db_url` to the same database as `db_url`, except using
an async driver; this will vary by database.

* resolve the url first, so the key into _ENGINE is correct

* Ping db connections before returning them from pool

Move connect engine kwargs to a separate function

* the param is `echo`

* sanity check that config db_url and async_db_url are the same

throw a warning if the part following the `://` differs between these two

* create_async_engine: use sqlalchemy async API

update types

* redact ASYNC_DB_URL similarly to DB_URL when overridden in config

* update rx.asession docstring

* use async_sessionmaker

* Redact sensitive env vars instead of hiding them
2024-12-10 12:37:09 -08:00
benedikt-bartscher
3ef7106e0e
style: prefer type() over __class__ (#4512) 2024-12-10 12:35:46 -08:00
Masen Furer
37af2ee1ec
Revert "reduce lock expiration time to 1s (#4507)" (#4514)
This reverts commit 6e3e632bbd.
2024-12-10 11:12:26 -08:00
Thomas Brandého
fd0fd2c6d4
enable REFURB rules in ruff (#4466)
Co-authored-by: Masen Furer <m_github@0x26.net>
2024-12-10 09:52:03 -08:00
benedikt-bartscher
2520c51aaf
fix: multiple mismatched-type-assignment fixes (#4482)
* fix: only make type optional if it's not already, add helper to unwrap rx.Field

* migrate unwrap_field_type to private function
2024-12-10 09:49:56 -08:00
Thomas Brandého
49a8f813fe
bump ruff to 0.8 and relock poetry (#4451)
* bump ruff to 0.8 and relock poetry

* bump to 0.8.1

* relock poetry.lock

* update again
2024-12-10 09:17:57 -08:00
Elijah Ahianyo
6e42efd2b1
Fix deploy help text (#4508) 2024-12-10 09:15:53 -08:00
Elijah Ahianyo
6e3e632bbd
reduce lock expiration time to 1s (#4507) 2024-12-10 09:15:22 -08:00
Elijah Ahianyo
05b791653e
Default rx.link href to # so underline prop works (#4509) 2024-12-10 09:14:29 -08:00
Thomas Brandého
4ecb0b81ce
enable RUF rules for linting (#4465) 2024-12-10 09:11:50 -08:00
Thomas Brandého
a68eef23aa
add issues templates (#4455)
* add issues templates

* fix typo
2024-12-10 15:37:58 +01:00
Masen Furer
0a34949019
Add production-one-port example (#4489)
* Add production-one-port example

A more complex version of simple-one-port that facilitates better layer caching
to shorten build times and multi-stage build to reduce final image size.

Harder to understand, but ultimately nicer to use.

* fix Caddyfile format to avoid complaints

* docker-examples: bump all base images to python:3.13
2024-12-09 15:26:48 -08:00
benedikt-bartscher
9ff386bf48
add __repr__ method to MutableProxy (#4506) 2024-12-10 00:17:51 +01:00
benedikt-bartscher
3d89d74bdc
only mark backend vars as dirty if they have changed (#4494) 2024-12-09 01:00:01 -08:00
Thomas Brandého
a895eaaede
fix non-interactive flag in deploy command (#4498) 2024-12-06 22:16:21 +01:00
benedikt-bartscher
3a225c2180
test dynamic route flakiness (can't reproduce locally) (#4496)
* test dynamic route flakiness (can't reproduce locally)

* fix typo
2024-12-06 17:41:53 +01:00
Masen Furer
3f4dca21a8
rename loginv2 to login (#4486)
* rename loginv2 to login

* reflex-hosting-cli bump to 0.1.29

* relock deps
2024-12-05 01:17:26 -08:00
Simon Young
12771004cb
remove v2 commands (#4478)
* remove v2 commands

* format

* remove v2

* remove v2

* little fixes friend

* add cloud

* relock poetry deps

* bump reflex-hosting-cli dep

* test_dynamic_routes: wait for token

attempt to avoid test flakiness

* relock deps

* test_dynamic_routes: increase polling timeout

---------

Co-authored-by: simon <simon@reflex.dev>
Co-authored-by: Masen Furer <m_github@0x26.net>
2024-12-04 23:21:18 -08:00
Elijah Ahianyo
e23d939781
[HOS-373][HOS-372]Logout should not open the browser (#4475)
* Logout should not open the browser

* check user login first before deploy
2024-12-04 18:17:22 -08:00
Masen Furer
a894f21ce5
[ENG-4149] require login to deploy named templates (#4450)
* integration_tests.yml: init masenf/rx_shout as a template

fix test

* [ENG-4149] require login to deploy template

* Send loginv2 telemetry event
2024-12-04 18:15:31 -08:00
Thomas Brandého
c721227a06
add default value for text area (#4462)
* add default_value prop in text_area

* also support it for el.textarea
2024-12-03 01:31:32 +01:00
Masen Furer
99d1b5fbdf
rx.upload must include _var_data from props (#4463)
* rx.upload must include _var_data from props

str-casting the dropzone arguments removed any VarData they depended on, like
the state context.

update test_upload to include passing a prop from a state var

* Handle large payload delta from upload event handler

Fix update chunk chaining logic; try/catch wasn't catching errors from the
async inner function.
2024-12-02 16:29:06 -08:00
Thomas Brandého
a320d062fb
enable css props via wrapperStyle for recharts components (#4447) 2024-12-02 09:20:33 -08:00
Masen Furer
39cdce6960
[HOS-333] Send a "reload" message to the frontend after state expiry (#4442)
* Unit test updates

* test_client_storage: simulate backend state expiry

* [HOS-333] Send a "reload" message to the frontend after state expiry

1. a state instance expires on the backing store
2. frontend attempts to process an event against the expired token and gets a
   fresh instance of the state without router_data set
3. backend sends a "reload" message on the websocket containing the event and
   immediately stops processing
4. in response to the "reload" message, frontend sends
   [hydrate, update client storage, on_load, <previous_event>]

This allows the frontend and backend to re-syncronize on the state of the app
before continuing to process regular events.

If the event in (2) is a special hydrate event, then it is processed normally
by the middleware and the "reload" logic is skipped since this indicates an
initial load or a browser refresh.

* unit tests working with redis
2024-11-28 13:56:41 +01:00
Masen Furer
24ff29f74d
bump to 0.6.7dev1 for further development (#4434) 2024-11-26 14:04:36 -08:00
Elijah Ahianyo
80696fec63
Remove invitation code logic from reflex logoutv2 (#4433)
* what happened there?

* we should do this for v2 instead
2024-11-25 12:14:50 -08:00
Thomas Brandého
f490643b25
follow up to #4426 (#4436) 2024-11-25 11:27:07 -08:00
Thomas Brandého
51ca89bc5c
allow for 'go.Figure | None' annotation in State (#4426) 2024-11-25 19:45:29 +01:00
benedikt-bartscher
d7d46e431b
fix: state size was not checked for dill (#4431) 2024-11-25 10:38:52 -08:00
Thomas Brandého
697e26c25b
fix mutable default in EventNamespace (#4420) 2024-11-23 10:51:07 -08:00
Masen Furer
c7d3876fe6
[ENG-4137] Handle generic alias passing inspect.isclass check (#4427)
On py3.9 and py3.10, `dict[str, str]` and other typing forms are kinda
considered classes, but they still fail when doing `issubclass`, so
specifically exclude generic aliases before calling issubclass.

Fix #4424

Bonus fix: support upcasting of pydantic v1 and v2 models
2024-11-23 10:48:50 -08:00
Masen Furer
000938414f
Avoid set_log_level foot gun (#4422) 2024-11-22 12:31:59 -08:00
Simon Young
c29c6b657a
Simon/hosting cli upgrades (#4417)
* update cli version

* little change man

* thats ruff

* v bump

---------

Co-authored-by: simon <simon@reflex.dev>
2024-11-21 17:50:35 -08:00
benedikt-bartscher
a5486335a3
rx._x.asset improvements (#3624)
* wip rx._x.asset improvements

* only add symlink if it doesn't already exist

* minor improvements, add more tests

* use deprecated Generator for python3.8 support

* improve docstring

* only allow explicit shared, only validate local assets if not backend_only

* fix darglint

* allow setting backend only env to false.

* use new is_backend_only in assets

* ruffing

* Move to `rx.asset`, retain old API in `rx._x.asset`

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-11-21 17:16:43 -08:00
Masen Furer
a6b324bd3e
[ENG-3953] Support pydantic BaseModel (v1 and v2) as state var (#4338)
* [ENG-3953] Support pydantic BaseModel (v1 and v2) as state var

Provide serializers and mutable proxy tracking for pydantic models directly.

* conditionally define v2 serializer

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>

* Add `MutableProxy._is_mutable_value` to avoid duplicate logic

* Conditionally import BaseModel to handle older pydantic v1 versions

* pre-commit fu

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-11-21 17:01:14 -08:00
Elijah Ahianyo
5702a18502
[GTM-836]Rework Init workflow (#4377)
* Rework Init workflow

* minor format

* refactor

* add comments

* fix pyright alongside some improvements

* add demolink for blank template

* fix darglint

* Add more templates and keep template name in kebab case

* revert getting other templates since we'll use the submodules approach

* remove debug statement

* Improvements based on standup comments

* Add redirect logic

* changes based on new flow

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-11-21 16:58:12 -08:00
Elijah Ahianyo
9faa5d6fd9
Downgrade syntax highlighter to fix wrapLongLines (#4368) 2024-11-21 16:54:15 -08:00
benedikt-bartscher
c13cec3d8a
implement performance mode for existing state size check (#4392) 2024-11-21 16:33:47 -08:00
Masen Furer
b5e4b02d9c
New Event Action: temporal (#4404)
When an event/event spec is marked as "temporal", it will not be queued unless
the backend is up. This can be used to prevent periodic events (like from
`rx.moment`) from queueing up while the backend is down, and then stampeding
when the backend comes up and the queue is drained. It can be used to avoid
processing many periodic events at once when the app is only expecting to
process such an event every so often.
2024-11-21 16:32:38 -08:00
Masen Furer
bbfbc82c9d
Handle Var passed to rx.toast (#4405)
* Handle Var passed to `rx.toast`

If the user provides a `Var` for `message` then apply it as `props["title"]` to
avoid a var operations error.

* remove unnecessary parentheses

* remove weird hacks

* get it right pyright

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-11-21 16:15:01 -08:00
Thomas Brandého
d4b197b517
fix for event handlers in py3.9 (#4416) 2024-11-21 12:41:48 -08:00
benedikt-bartscher
e0984aa834
Allow bound method as event handler (#4348)
* subtract 1 arg if the method is a bound method

* fix it early in user_args

* only bound methods pls

* add test
2024-11-21 11:53:50 -08:00
benedikt-bartscher
ecb52651c3
allow to disable checking for the latest package version via env (#4407) 2024-11-21 11:06:47 -08:00
Thomas Brandého
095c1e5b7f
remove deprecation for these events (#4415) 2024-11-21 11:05:02 -08:00
Masen Furer
05956c84a7
protect sys.path manipulation with a mutex (#4408)
Compiling pages in separate threads can result in `sys.path` being cleared,
which breaks subsequent imports.
2024-11-21 10:29:40 -08:00
Masen Furer
81583d45ca
[HOS-313] state.js: when a routing error occurs, delete it (#4410)
In some cases, a routing failure can cause the failure to be cached. When the
router has a cached failure, pushing such a route will never call
routeChangeComplete, and thus on_load event will never be fired for that route.

Purposely clearing the error from the router allows the page to properly load
on subsequent attempts without refreshing the app.
2024-11-21 10:27:44 -08:00
Masen Furer
4571524e1c
[ENG-4130] Disable typer/rich integration appropriately (#4412)
The `rich` module should be set to `None`, indicating that rich should not be used.

Setting it to `False` worked before, but recently added code in typer fails
when checking `if rich is not None`.

ref: https://github.com/fastapi/typer/pull/847
2024-11-21 13:11:34 +01:00
Thomas Brandého
681b616000
fix appearance broken by #3812 (#4403)
* fix appearance broken by #3812

* fix again to pass tests
2024-11-20 11:12:52 -08:00
Khaleel Al-Adhami
229df1ce09
ignore rxconfig not in cwd (#4398)
* ignore rxconfig not in cwd

* no type ignore

* resolve paths

* Remove rxconfig module from sys.modules cache when reloading

* modify sys path

* add try except

* refactor inner function

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-11-19 16:46:55 -08:00
Masen Furer
67296d43c0
Don't skip serialization when Var is callable (#4399) 2024-11-19 16:33:27 -08:00
Alek Petuskey
bffff01acb
Add datetime to moment (#4381)
* Add datetime to moment

* Remove recharts update

* Support other formats

* simplify

* Precommit

* PYI

* change imports for pyi compat

---------

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Masen Furer <m_github@0x26.net>
2024-11-19 09:29:11 -08:00
Khaleel Al-Adhami
bcea79cd45
add typed dict type checking (#4340)
* add typed dict type checking

* technically it has to be a mapping, not specifically a dict
2024-11-18 19:28:38 -08:00
benedikt-bartscher
1f9a17539c
fix: do not allow instantiation of State mixins (#4347)
* fix: do not allow instantiation of State mixins
Closes #4343

* improve error message for ComponentState mixins

* fix typo

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-11-18 19:15:01 -08:00
Thomas Brandého
af4fe48428
[maintenance] bump some packages versions (#4385)
* bump some versions

* update ruff to 0.7.4

* bump tailwind version

* relock deps

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-11-18 18:56:28 -08:00
Thomas Brandého
adaf49e4f9
make list suggestions work in rx.input (#4391)
* make list suggestions work

* fix pyi
2024-11-18 18:22:01 -08:00
Khaleel Al-Adhami
22329e592e
add debug statement to evaluate page (#4396) 2024-11-18 18:21:45 -08:00
Simon Young
3f58ceef95
update cli version (#4394)
Co-authored-by: simon <simon@reflex.dev>
2024-11-18 16:59:54 -08:00
Masen Furer
6494683c27
Fix ternary logic when printing template name (#4393) 2024-11-19 00:11:04 +01:00
Masen Furer
34c11fdf10
require typing_extensions >= 4.6.0 (#4373)
* require typing_extensions >= 4.6.0

TypeAliasType was added in 4.6

https://github.com/python/typing_extensions/blob/main/CHANGELOG.md#release-460-may-22-2023

* update lock file, even though nothing has changed
2024-11-18 10:31:11 -08:00
benedikt-bartscher
dc347d10b3
fix: Failed to CreateArtifact (#4339) 2024-11-15 16:27:05 -08:00
Thomas Brandého
e45b76c01e
fix noSSRComponent imports (#4386) 2024-11-15 21:43:55 +01:00
Alek Petuskey
79a5409a8e
Update bug_report.md (#4382) 2024-11-13 20:42:29 -08:00
Elijah Ahianyo
853a9d8614
Add template name to reflex init success msg (#4349)
* Add template name to reflex init success msg

* fix pyright message
2024-11-13 10:24:36 +00:00
Khaleel Al-Adhami
27c1a7e94d
add typing to function vars (#4372)
* add typing to function vars

* import ParamSpec from typing_extensions

* remove ellipsis as they are not supported in 3.9

* try importing everything from extensions

* special case 3.9

* don't use Any from extensions

* get typevar from extensions
2024-11-12 20:00:02 -08:00
Masen Furer
5d88263cd8
[ENG-4098] Deconfuse key/value of State.get_value / dict / get_delta (#4371)
Because of some dodgy logic in Base.get_value and State.dict / State.get_delta
when the value of some state var X happened to be the name of another var in
the state Y, then the value for X would be returned as the value of Y.

wat.

Fixes #4369
2024-11-12 13:24:06 -08:00
Masen Furer
2b7ef0dccc
Temporarily downpin @radix-ui/themes <3.1.5 (#4370)
* Temporarily downpin @radix-ui/themes <3.1.5

A visual/style regression was introduced in @radix-ui/themes 3.1.5
as described in radix-ui/themes#627 which reflex needs to avoid.

* Get expected radix library version from component
2024-11-12 12:44:59 -08:00
Khaleel Al-Adhami
a1158cdb1c
redesign error boundary screen (#4329)
* redesign error boundary screen

* pyi time

* add color

* i hate python 3.9
2024-11-12 12:36:42 -08:00
1Codev
7cf3050da0
Path change after Astral 0.5.0 update (#4336)
* Astral 0.5.0 path change

https://github.com/astral-sh/uv/releases

Use XDG (i.e. ~/.local/bin) instead of the Cargo home directory in the installer

* Fix path in production-app-platform example

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-11-12 09:57:58 -08:00
Masen Furer
686548cbb1
Only pass Model.__fields__ when casting event args (#4356)
Attempting to initialize relationship fields in a sqlmodel model throws an
error, so only pass defined pydantic __fields__ if the type is a Model.
2024-11-11 16:14:08 -08:00
Masen Furer
35c8afd8c8
Bump reflex-hosting-cli dep to 0.1.15 for v2 (#4355) 2024-11-11 16:12:01 -08:00
Masen Furer
082f9a0bd1
export Color and ImportDict in top-level namespace (#4352)
These are useful for typing purposes and should be exposed at the top level to
avoid requiring deep imports from subpackages that we may need to change later.
2024-11-11 14:41:31 -08:00
Masen Furer
f78e3f54ef
bump to 0.6.6dev1 for further development (#4351) 2024-11-11 14:41:18 -08:00
Khaleel Al-Adhami
e0d1a58496
fix upload argspec being missing (#4335) 2024-11-08 10:12:29 -08:00
Elijah Ahianyo
cd59ab5406
[ENG-4010]Codeblock cleanup in markdown (#4233)
* Codeblock cleanup in markdown

* Initial approach to getting this working with rx.memo and reflex web

* abstract the map var logic

* the tests are not valid + pyright fix

* darglint fix

* Add unit tests plus mix components

* pyi run

* rebase on main

* fix darglint

* testing different OS

* revert

* This should fix it. Right?

* Fix tests

* minor fn signature fix

* use ArgsFunctionOperation

* use destructured args and pass the tests

* fix remaining unit tests

* fix pyi files

* rebase on main

* move language regex on codeblock to markdown

* fix tests

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-11-07 19:18:14 -08:00
Simon Young
3d85936009
update cli version (#4333)
Co-authored-by: simon <simon@reflex.dev>
2024-11-07 19:17:55 -08:00
Khaleel Al-Adhami
a454b705a8
fix imports with alias from $ (#4332) 2024-11-07 19:17:07 -08:00
Khaleel Al-Adhami
4c4c59bf04
convert event return types to type hints (#4331) 2024-11-07 16:33:42 -08:00
Masen Furer
2ee2d52035
Fix pyi file merged after custom_attrs type change (#4330) 2024-11-07 16:18:28 -08:00
Elijah Ahianyo
855a20fd1c
[GTM-648]Add Missing Table props (#4322)
* Add Missing Table props

* add more props
2024-11-07 16:04:03 -08:00
Masen Furer
227d09a02c
test_exception_handlers: add test case that triggers ErrorBoundary (#4327) 2024-11-07 16:01:37 -08:00
benedikt-bartscher
8fd5c9f200
improve typing for serializer decorator (#4317)
* improve typing for serializer decorator

* use wrapped logic

* dang it darglint

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-11-07 15:52:11 -08:00
Khaleel Al-Adhami
0c482bda3c
mark var methods as private (#4319) 2024-11-07 14:50:26 -08:00
Khaleel Al-Adhami
7843a517bc
change custom attr to accept any (#4323) 2024-11-07 14:18:13 -08:00
benedikt-bartscher
2cb193e8d6
improve app_src typing (#4324) 2024-11-07 14:08:37 -08:00
Simon Young
e457d53924
Adding hosting v1 support (#4309)
Co-authored-by: simon <simon@reflex.dev>
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-11-06 17:18:41 -08:00
Khaleel Al-Adhami
68407ce2d8
unbreak pyi plotly (#4320) 2024-11-06 16:56:26 -08:00
Khaleel Al-Adhami
3bd35f53f2
add type hinting for plotly (#4279)
* add type hinting for plotly

* fix merge
2024-11-06 16:41:13 -08:00
Khaleel Al-Adhami
93ae79aa60
fix call_function events sent from backend (#4316) 2024-11-06 15:13:00 -08:00
Khaleel Al-Adhami
b9d73edd66
add metainfo to keyevent (#4287)
* allow for event handlers to ignore args

* use a constant

* dang it darglint

* forgor

* keep the tests but move them to valid place

* add metainfo to keyevent

* format code

* fix pyi files

* generate all prefixes of event types

* change format rule
2024-11-06 15:10:02 -08:00
Thomas Brandého
4c0b49135b
stop ignoring some lint rules (#4311)
* bump python packages version

* stop ignoring some lint rules that pass ruff check

* stop ignoring rule F541

* remove sneaky test file
2024-11-06 13:32:31 -08:00
Khaleel Al-Adhami
6ea797d0cd
pin marked to correct version (#4313)
* pin marked to correct version

* remove it completely?

* missing quotations

* match against reflex
2024-11-06 11:28:08 -08:00
Carlos
8a4701143e
add toast classname prop (#4310) 2024-11-06 09:49:09 -08:00
Thomas Brandého
54b081c104
allow custom bunfig.toml file (#4280)
* allow custom bunfig.toml file

* always copy custom bunfig

* split tests into half

* forgot a space

* use different syntax

* also split node latest check

* turn off failfast for app harness

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-11-06 09:31:13 -08:00
Simon Young
8d5187432f
add codeowners (#4312)
Co-authored-by: simon <simon@reflex.dev>
2024-11-06 09:30:43 -08:00
Khaleel Al-Adhami
c57d496184
improve typing for non decorated events (#4308)
* improve typing for non decorated events

* fix any typing
2024-11-06 09:21:19 -08:00
Khaleel Al-Adhami
bfa7ca639f
better missing system package message (#4306)
* better missing system package message

* change error type
2024-11-06 09:21:04 -08:00
Khaleel Al-Adhami
6334cfab0d
allow for event handlers to ignore args (#4282)
* allow for event handlers to ignore args

* use a constant

* dang it darglint

* forgor

* keep the tests but move them to valid place
2024-11-06 09:20:37 -08:00
simon
d9ab3a0f1c Revert "add v1 support"
This reverts commit c216eeafeb.
2024-11-05 18:28:16 -08:00
simon
c216eeafeb add v1 support 2024-11-05 18:23:18 -08:00
Carlos
01e3844ac4
default props comment for GraphinTooltip (#4101)
* default props comment for GraphinTooltip

* update
2024-11-05 14:03:07 -08:00
benedikt-bartscher
4a6c16e9dc
More env var cleanup (#4248)
* fix and test bug in config env loading

* streamline env var interpretation with @adhami3310

* improve error messages, fix invalid value for TELEMETRY_ENABLED

* just a small hint

* ruffing

* fix typo from review

* refactor - ruff broke the imports..

* cleanup imports

* more

* add internal and enum env var support

* ruff cleanup

* more global imports

* revert telemetry, it lives in rx.Config

* minor fixes/cleanup

* i missed some refs

* fix darglint

* reload config is internal

* fix EnvVar name

* add test for EnvVar + minor typing improvement

* bool tests

* was this broken?

* retain old behavior

* migrate APP_HARNESS_HEADLESS to new env var system

* migrate more APP_HARNESS env vars to new config system

* migrate SCREENSHOT_DIR to new env var system

* refactor EnvVar.get to be a method

* readd deleted functions and deprecate them

* improve EnvVar api, cleanup RELOAD_CONFIG question

* move is_prod_mode back to where it was
2024-11-05 12:25:13 -08:00
Thomas Brandého
1c4f410052
bump python packages version (#4302) 2024-11-05 10:50:43 -08:00
Thomas Brandého
ce22ca5f71
rollback to 14.2.16 until v15 is more stable (#4297) 2024-11-05 10:50:32 -08:00
Khaleel Al-Adhami
b5d1e03de1
improve object var symantics (#4290)
* improve object var symantics

* add case for serializers

* check against serializer with to = dict

* add tests

* fix typing issues

* remove default value

* older version of python doesn't have assert type

* add base to rx field cases

* get it from typing_extension
2024-11-05 09:56:10 -08:00
Thomas Brandého
0ed7c5d969
expose rx.get_state() to get instance of state from anywhere (#3959)
* expose rx.get_state() to get instance of state from anywhere

* fix circular import and add read-only proxy
2024-11-05 16:21:59 +01:00
abulvenz
bb903b605a
Fix wrong hook (#4295)
* fix: Typo in variable name.

* fix: Using existing hook constant.

---------

Co-authored-by: Benedikt Bartscher <bb@senbax.de>
2024-11-04 15:20:02 -08:00
Khaleel Al-Adhami
1122cbf0b1
handle none case in state setattr (#4301) 2024-11-04 14:37:58 -08:00
benedikt-bartscher
b3c199870e
bypass pydantic runtime validation for state init (#4256)
* bypass pydantic runtime validation for state init
closes #4235

* cleanup
2024-11-04 13:05:39 -08:00
graham
702808afa6
Bugfix/leave gitignore as is (#4291)
* Refactor initialize_gitignore to support list type for files_to_ignore and improve current ignore handling.  Dont sort the gitignore file.

* more consistent list comprehension var
2024-11-04 11:36:12 -08:00
Khaleel Al-Adhami
51b0f7d28e
special case field in _isinstance (#4298) 2024-11-04 11:06:24 -08:00
Khaleel Al-Adhami
16ed266d11
move check of path to only check name (#4299)
* move check of path to only check name

* assert .name in other tests as well

* get even more ones
2024-11-04 11:01:14 -08:00
Khaleel Al-Adhami
ca81e623db
add noop event (#4288)
* add noop event

* fix pyi

* get it right pyright

* why

* remove silly events

* fix tests

* remove semi colon

* errors in merging
2024-11-04 10:33:07 -08:00
Khaleel Al-Adhami
6394a6dfc5
raise error when get package manager is not found (#4289)
* raise error when get package manager is not found

* add escape hatch

* handle installing frontend packages more gracefully

* fix no return

* dang it darglint
2024-11-04 10:31:24 -08:00
Masen Furer
163acf70a2
[ENG-759] [ENG-1104] patch json.dumps to handle __wrapped__ objects (#4166)
* [ENG-1104] patch `json.dumps` to handle `__wrapped__` objects

Unwrap proxied objects if the default serializer doesn't work.

* pre-commit fixup

* Skip default fallback logic when `cls` is specified

`cls` will provide its own default serialization mechanism, passing a `cls`
Encoder class is now also a way to opt-out of our patching shenanigans and just
use your own code.

This will work, provided the library doing the JSON encoding isn't also using
their own custom class.

* Override JSONEncoder.default instead of json.dumps

Many libraries (like httpx, used by openai), will use `from json import dumps`,
and if they do that before `reflex.state` gets imported, then they will get the
original dumps function instead of our patched one.

To workaround this, monkeypatch the `JSONEncoder.default` function instead.

This is also nicer behavior for custom subclasses of JSONEncoder; if someone
wants to opt-out of our monkeypatching, they can simply not call
`super().default(o)` in their subclass, which by default only raises a
TypeError.

---------

Co-authored-by: Nikhil Rao <nikhil@reflex.dev>
2024-11-04 10:11:51 -08:00
Masen Furer
0d9fc53a7d
[REF-3961] move "warn_if_too_large" logic into BaseState (#4284)
Check for too large serialized state whenever `BaseState._serialize` is used,
so it can apply to all state managers, not just `StateManagerRedis`.
2024-11-04 10:11:04 -08:00
Tom Gotsman
b70f33d972
Update overlay props (#4261)
* hover card and one prop for dialog

* add missing props of drawer

* fix context and dropdown menu

* add popover props

* fix hover card and alert dialog final

* fix pyi

* update drawer pyi

* pyi fix again

* fix from masen changes

* fix pyi

* fix pyi again

* ruff fix

---------

Co-authored-by: Tom Gotsman <tomgotsman@Toms-MacBook-Pro.local>
2024-11-01 16:14:46 -07:00
Elijah Ahianyo
bcd51779e6
[GTM-345]Define component props in class for doc discoverability (#4183)
* Define component props in class for doc discoverability

* add other files

* fix accordion typing

* add more

* pyright fix

* pyi fix

* pyi fix fr

* resinstate connection banner api

* precommit fix

* fix reflex-web test for select

* exclude props we don't need from compiling.
use regular model fields where necessary

* fix counter tests

* list partial fix

* list fix

* list fix

* precommit fix

* Accept suggestions

* Update reflex/components/radix/primitives/accordion.py

Co-authored-by: Masen Furer <m_github@0x26.net>

* address missed comment

* pyright fix

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-11-01 10:55:02 +00:00
Elijah Ahianyo
dbc9ab2d63
change gallery link to Templates (#4283) 2024-10-31 17:14:53 -07:00
Thomas Brandého
c07eb2a6a0
[ENG-3943]type check for event handler if spec arg are typed (#4046)
* type check for event handler if spec arg are typed

* fix the typecheck logic

* rearrange logic pieces

* add try except

* add try except around compare

* change form and improve type checking

* print key instead

* dang it darglint

* change wording

* add basic test to cover it

* add a slightly more complicated test

* challenge it a bit by doing small capital list

* add multiple argspec

* fix slider event order

* i hate 3.9

* add note for UnionType

* move function to types

* add a test for type hint is subclass

* make on submit dict str any

* add testing for dict cases

* add check against any

* accept dict str str

* bruh i used i twice

* escape strings and print actual error message

* disable the error and print deprecation warning instead

* disable tests

* fix doc message

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-10-31 12:45:28 -07:00
Khaleel Al-Adhami
c8cecbf3cc
fix typo in dataeditor prop (#4281)
* fix typo in dataeditor prop

* move other ones as well
2024-10-31 11:20:15 -07:00
Elijah Ahianyo
a968231750
[ENG-3892]Shiki codeblock support decorations (#4234)
* Shiki codeblock support decorations

* add decorations to useEffect

* fix pyright

* validate decorations dict

* Fix exception message plus unit tests

* possible test fix

* fix pyright

* possible tests fix

* cast decorations before creating codeblock

* `plain` is not a valid theme

* pyi fix

* address PR comment
2024-10-31 09:33:49 +00:00
Nikhil Rao
84b0864e7e
Add option to scroll to bottom (#4276)
* Add option to scroll to bottom

* use var shenangins

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-10-30 17:57:38 -07:00
Khaleel Al-Adhami
e5e494108e
improve page title default (#4278) 2024-10-30 17:48:23 -07:00
Khaleel Al-Adhami
a2126beca1
generate docs for event handlers (#4277) 2024-10-30 17:31:38 -07:00
Khaleel Al-Adhami
4254eadce3
use better typing for on_load (#4274)
* use better typing for on_load

* make app dataclass

* get it right pyright

* make lifespan into a dataclass
2024-10-30 16:52:16 -07:00
Masen Furer
2ab662b757
[ENG-4013] Catch more exceptions for dill pickle fallback (#4270)
Additionally catch TypeError, IndexError, and ValueError which may be thrown
when attempting to pickle unpicklable objects.
2024-10-30 16:50:19 -07:00
Khaleel Al-Adhami
c288741cab
resync steps with task advance (#4275) 2024-10-30 15:16:34 -07:00
Khaleel Al-Adhami
141cb8d21b
unbreak ci lighthouse (#4273)
* unbreak ci lighthouse

* forgot to precommit
2024-10-30 15:16:16 -07:00
benedikt-bartscher
0bdc828889
cleanup dead code (#4271) 2024-10-30 13:58:22 -07:00
Khaleel Al-Adhami
24363170d3
components as literal vars (#4223)
* component as literal vars

* fix pyi

* use render

* fix pyi

* only render once

* add type ignore

* fix upload default value

* remove testcases if you don't pass them

* improve behavior

* fix render

* that's not how icon buttons work

* upgrade to next js 15 and remove babel and enable turbo

* upload is a silly guy

* woops

* how did this work before

* set env variable

* lower it even more

* lower it even more

* lower it even more

* only do literals as component vars
2024-10-30 11:31:28 -07:00
Khaleel Al-Adhami
c8a7ee52bf
add type validation for state setattr (#4265)
* add type validation for state setattr

* add type to check to state setattr

* add type validation to computed vars
2024-10-30 11:11:03 -07:00
Khaleel Al-Adhami
4260a0cfc3
rx.event(background=True) (#4263)
* event background True

* fix typo

* fix overloads

* forgor

* remove extra parens

* more forgor
2024-10-30 11:10:51 -07:00
Elijah Ahianyo
d6540b192e
Fix for shiki copy button animation firing off after clicking copy button (#4252) 2024-10-30 15:54:22 +00:00
Khaleel Al-Adhami
d478387007
expose staticPageGenerationTimeout (#4266)
* expose staticPageGenerationTimeout

* update tests
2024-10-29 22:02:35 -07:00
Khaleel Al-Adhami
1f627c5a30
update nodejs to lts 22 for real this time (#4267) 2024-10-29 22:02:21 -07:00
Khaleel Al-Adhami
98394ceb8e
add existing path subclass for env checks (#4260)
* add existing path subclass for env checks

* use the power of dataclasses

* use metaclass

* fake the class name

* use annotated

* use flag instead of dict

* dang it darglint

* cleanups
2024-10-29 13:02:10 -07:00
Masen Furer
8f07082eba
Handle props annotated as list/dict of EventHandler (#4257)
These props are NOT event triggers themselves, but rather they are props that
expect a list or dict of event handlers.

Additional fix for calling an `@rx.event` decorated event handler with no
arguments.
2024-10-28 16:59:26 -07:00
Khaleel Al-Adhami
41b1958626
fix stateful components on delayed evaluation (#4247)
* fix stateful components on delayed evaluation

* remove unused code

* ignore custom components in stateful components

* skip ones with wraps

* fix order of operations and add note
2024-10-28 12:13:46 -07:00
benedikt-bartscher
08d8d54b50
port enum env var support from #4248 (#4251)
* port enum env var support from #4248

* add some tests for interpret env var functions
2024-10-28 11:56:40 -07:00
Luca Baffa
01ca42648b
remove duplicate 'gray' color (#4249) 2024-10-28 09:27:21 -07:00
Khaleel Al-Adhami
ab4fd41e55
make vardata merge not use classmethod (#4245)
* make vardata merge not use classmethod

* add clarifying comment

* use simple cases for small values

* add possible None

* allow zero values to be given to var data

* dang it darglint
2024-10-25 17:34:47 -07:00
Thomas Brandého
e47cd25275
upgrade to nextJS v15 (#4243)
* upgrade to next 15

* relock poetry file

* test options

* skip windows on reflex-web

* bump min node version

* add turbo for dev command

* remove turbo flag
2024-10-26 02:27:44 +02:00
Masen Furer
83cfcc63f1
pyproject: bump to 0.6.5dev1 for future development (#4246) 2024-10-25 13:51:33 -07:00
Khaleel Al-Adhami
788b21556d
delay page until _compile gets called (#3812)
* basic functionality

* reorder page evaluation

* Fix benchmark tests (#3822)

* Upper bound for reflex-chakra dependency (#3824)

* Upper bound for reflex-chakra dependency

We have to make a breaking change in reflex-chakra, and it will happen in 0.6.0, so ensure that reflex 0.5.10 never installs the breaking version of reflex-chakra.

* Relock deps

* Add comments to DataList components (#3827)

* fix: Adding missing comments to the data list

* fix: Ran make pyi

* fully migrate vars into new system (#3743)

* fully migrate vars into new system

* i hate rufffff (no i don't)

* fix silly pright issues (except colormode and state)

* remove all instances of Var.create

* create immutable callable var and get rid of more base vars

* implement hash for all functions

* get reflex-web to compile

* get it to compile reflex-web successfully

* fix tests

* fix pyi

* use override from typing_extension

* put plotly inside of a catch

* dicts are unusable sadly

* fix silly mistake

* overload equals to special case immutable var

* improve test_cond

* solve more CI issues, down to 94 failures

* down to 20 errors

* down to 13 errors

* pass all testcases

* fix pyright issues

* reorder things

* use get origin more

* use fixed_type logic

* various optimizations

* go back to passing test cases

* use less boilerplate

* remove unnecessary print message

* remove weird comment

* add test for html issue

* add type ignore

* fix another silly issue

* override get all var data for var operations call

* make integration tests pass

* fix immutable call var

* better logic for finding parent class

* use even better logic for finding state wrt computedvar

* only choose the ones that are defined in the same module

* small dict to large dict

* [REF-3591] Remove chakra-related files from immutable vars PR (#3821)

* Add comments to html metadata component (#3731)

* fix: add verification for path /404 (#3723)

Co-authored-by: coolstorm <manas.gupta@fampay.in>

* Use the new state name when setting `is_hydrated` to false (#3738)

* Use `._is_mutable()` to account for parent state proxy (#3739)

When a parent state proxy is set, also allow child StateProxy._self_mutable to
override the parent's `_is_mutable()`.

* bump to 0.5.9 (#3746)

* add message when installing requirements.txt is needed for chosen template during init (#3750)

* #3752 bugfix add domain for XAxis (#3764)

* fix appharness app_source typing (#3777)

* fix import clash between connectionToaster and hooks.useState (#3749)

* use different registry when in china, fixes #3700 (#3702)

* do not reload compilation if using local app in AppHarness (#3790)

* do not reload if using local app

* Update reflex/testing.py

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>

* Bump memory on relevant actions (#3781)

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>

* [REF-3334] Validate Toast Props (#3793)

* [REF-3536][REF-3537][REF-3541] Move chakra components into its repo(reflex-chakra) (#3798)

* fix get_uuid_string_var (#3795)

* minor State cleanup (#3768)

* Fix code wrap in markdown (#3755)

---------

Co-authored-by: Alek Petuskey <alek@pynecone.io>
Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com>
Co-authored-by: coolstorm <manas.gupta@fampay.in>
Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>

* pyproject.toml: bump to 0.6.0a1

* pyproject.toml: depend on reflex-chakra>=0.6.0a

New Var system support in reflex-chakra 0.6.0a1

* poetry.lock: relock dependencies

* integration: bump listening timeout to 1200 seconds

* integration: bump listening timeout to 1800 seconds

* Use cached_var_no_lock to avoid ImmutableVar deadlocks (#3835)

* Use cached_var_no_lock to avoid ImmutableVar deadlocks

ImmutableVar subclasses will always return the same value for a _var_name or
_get_all_var_data so there is no need to use a per-class lock to protect a
cached attribute on an instance, and doing so actually is observed to cause
deadlocks when a particular _cached_var_name creates new LiteralVar instances
and attempts to serialize them.

* remove unused module global

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: Alek Petuskey <alek@pynecone.io>
Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com>
Co-authored-by: coolstorm <manas.gupta@fampay.in>
Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>

* guess_type: if the type is optional, treat it like it's "not None" (#3839)

* guess_type: if the type is optional, treat it like it's "not None"

When guessing the type for an Optional annotation, the Optional was already
being stripped off, but this value was being ignored, except for error
messages. So actually use the Optional-stripped value.

* Strip Optional when casting Var .to

* Fix double-quoting of defaultColorMode (#3840)

If the user provided an `appearance` or `color_mode` value to `rx.theme`, then
the resulting value ended up being double-double-quoted in the resulting JS
output.

Instead remove the quotes from the context.js.jinja2 and always pass appearance
as a Var.

* basic functionality

* run pyright

* fully migrate vars into new system (#3743)

* fully migrate vars into new system

* i hate rufffff (no i don't)

* fix silly pright issues (except colormode and state)

* remove all instances of Var.create

* create immutable callable var and get rid of more base vars

* implement hash for all functions

* get reflex-web to compile

* get it to compile reflex-web successfully

* fix tests

* fix pyi

* use override from typing_extension

* put plotly inside of a catch

* dicts are unusable sadly

* fix silly mistake

* overload equals to special case immutable var

* improve test_cond

* solve more CI issues, down to 94 failures

* down to 20 errors

* down to 13 errors

* pass all testcases

* fix pyright issues

* reorder things

* use get origin more

* use fixed_type logic

* various optimizations

* go back to passing test cases

* use less boilerplate

* remove unnecessary print message

* remove weird comment

* add test for html issue

* add type ignore

* fix another silly issue

* override get all var data for var operations call

* make integration tests pass

* fix immutable call var

* better logic for finding parent class

* use even better logic for finding state wrt computedvar

* only choose the ones that are defined in the same module

* small dict to large dict

* [REF-3591] Remove chakra-related files from immutable vars PR (#3821)

* Add comments to html metadata component (#3731)

* fix: add verification for path /404 (#3723)

Co-authored-by: coolstorm <manas.gupta@fampay.in>

* Use the new state name when setting `is_hydrated` to false (#3738)

* Use `._is_mutable()` to account for parent state proxy (#3739)

When a parent state proxy is set, also allow child StateProxy._self_mutable to
override the parent's `_is_mutable()`.

* bump to 0.5.9 (#3746)

* add message when installing requirements.txt is needed for chosen template during init (#3750)

* #3752 bugfix add domain for XAxis (#3764)

* fix appharness app_source typing (#3777)

* fix import clash between connectionToaster and hooks.useState (#3749)

* use different registry when in china, fixes #3700 (#3702)

* do not reload compilation if using local app in AppHarness (#3790)

* do not reload if using local app

* Update reflex/testing.py

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>

* Bump memory on relevant actions (#3781)

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>

* [REF-3334] Validate Toast Props (#3793)

* [REF-3536][REF-3537][REF-3541] Move chakra components into its repo(reflex-chakra) (#3798)

* fix get_uuid_string_var (#3795)

* minor State cleanup (#3768)

* Fix code wrap in markdown (#3755)

---------

Co-authored-by: Alek Petuskey <alek@pynecone.io>
Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com>
Co-authored-by: coolstorm <manas.gupta@fampay.in>
Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>

* pyproject.toml: bump to 0.6.0a1

* pyproject.toml: depend on reflex-chakra>=0.6.0a

New Var system support in reflex-chakra 0.6.0a1

* poetry.lock: relock dependencies

* integration: bump listening timeout to 1200 seconds

* integration: bump listening timeout to 1800 seconds

* Use cached_var_no_lock to avoid ImmutableVar deadlocks (#3835)

* Use cached_var_no_lock to avoid ImmutableVar deadlocks

ImmutableVar subclasses will always return the same value for a _var_name or
_get_all_var_data so there is no need to use a per-class lock to protect a
cached attribute on an instance, and doing so actually is observed to cause
deadlocks when a particular _cached_var_name creates new LiteralVar instances
and attempts to serialize them.

* remove unused module global

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: Alek Petuskey <alek@pynecone.io>
Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com>
Co-authored-by: coolstorm <manas.gupta@fampay.in>
Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>

* basic functionality

* reorder page evaluation

* fully migrate vars into new system (#3743)

* fully migrate vars into new system

* i hate rufffff (no i don't)

* fix silly pright issues (except colormode and state)

* remove all instances of Var.create

* create immutable callable var and get rid of more base vars

* implement hash for all functions

* get reflex-web to compile

* get it to compile reflex-web successfully

* fix tests

* fix pyi

* use override from typing_extension

* put plotly inside of a catch

* dicts are unusable sadly

* fix silly mistake

* overload equals to special case immutable var

* improve test_cond

* solve more CI issues, down to 94 failures

* down to 20 errors

* down to 13 errors

* pass all testcases

* fix pyright issues

* reorder things

* use get origin more

* use fixed_type logic

* various optimizations

* go back to passing test cases

* use less boilerplate

* remove unnecessary print message

* remove weird comment

* add test for html issue

* add type ignore

* fix another silly issue

* override get all var data for var operations call

* make integration tests pass

* fix immutable call var

* better logic for finding parent class

* use even better logic for finding state wrt computedvar

* only choose the ones that are defined in the same module

* small dict to large dict

* [REF-3591] Remove chakra-related files from immutable vars PR (#3821)

* Add comments to html metadata component (#3731)

* fix: add verification for path /404 (#3723)

Co-authored-by: coolstorm <manas.gupta@fampay.in>

* Use the new state name when setting `is_hydrated` to false (#3738)

* Use `._is_mutable()` to account for parent state proxy (#3739)

When a parent state proxy is set, also allow child StateProxy._self_mutable to
override the parent's `_is_mutable()`.

* bump to 0.5.9 (#3746)

* add message when installing requirements.txt is needed for chosen template during init (#3750)

* #3752 bugfix add domain for XAxis (#3764)

* fix appharness app_source typing (#3777)

* fix import clash between connectionToaster and hooks.useState (#3749)

* use different registry when in china, fixes #3700 (#3702)

* do not reload compilation if using local app in AppHarness (#3790)

* do not reload if using local app

* Update reflex/testing.py

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>

* Bump memory on relevant actions (#3781)

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>

* [REF-3334] Validate Toast Props (#3793)

* [REF-3536][REF-3537][REF-3541] Move chakra components into its repo(reflex-chakra) (#3798)

* fix get_uuid_string_var (#3795)

* minor State cleanup (#3768)

* Fix code wrap in markdown (#3755)

---------

Co-authored-by: Alek Petuskey <alek@pynecone.io>
Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com>
Co-authored-by: coolstorm <manas.gupta@fampay.in>
Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>

* pyproject.toml: bump to 0.6.0a1

* pyproject.toml: depend on reflex-chakra>=0.6.0a

New Var system support in reflex-chakra 0.6.0a1

* poetry.lock: relock dependencies

* integration: bump listening timeout to 1200 seconds

* integration: bump listening timeout to 1800 seconds

* Use cached_var_no_lock to avoid ImmutableVar deadlocks (#3835)

* Use cached_var_no_lock to avoid ImmutableVar deadlocks

ImmutableVar subclasses will always return the same value for a _var_name or
_get_all_var_data so there is no need to use a per-class lock to protect a
cached attribute on an instance, and doing so actually is observed to cause
deadlocks when a particular _cached_var_name creates new LiteralVar instances
and attempts to serialize them.

* remove unused module global

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: Alek Petuskey <alek@pynecone.io>
Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com>
Co-authored-by: coolstorm <manas.gupta@fampay.in>
Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>

* guess_type: if the type is optional, treat it like it's "not None" (#3839)

* guess_type: if the type is optional, treat it like it's "not None"

When guessing the type for an Optional annotation, the Optional was already
being stripped off, but this value was being ignored, except for error
messages. So actually use the Optional-stripped value.

* Strip Optional when casting Var .to

* run format

* use original mp

* evaluate page regardless

* use old typing

* dangit pydantic

* i have two braincells and they are NOT collaborating

* adjust testcases

* always add the upload endpoint

* retrieve upload but after evaluate component

* check against none

Co-authored-by: Masen Furer <m_github@0x26.net>

* make it var

* fix page title

* don't change style.py

* fix counter

* remove duplicated logic

---------

Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>
Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: elvis kahoro <elvis@reflex.dev>
Co-authored-by: Alek Petuskey <alek@pynecone.io>
Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com>
Co-authored-by: coolstorm <manas.gupta@fampay.in>
Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
2024-10-25 13:25:33 -07:00
Masen Furer
dcb73870d0
client_state: fix fault VarData.merge call (#4244)
VarData.merge is a classmethod, it's never bound to an instance of VarData
2024-10-25 21:33:34 +02:00
Masen Furer
6341846cea
Include value._get_all_var_data when ClientStateVar.set_value is used (#4161)
If `set_value` is called with a State var as the argument, ensure that its
context is brought into scope.
2024-10-25 11:43:55 -07:00
Masen Furer
f2bcb47986
Support locale prop for rx.moment (#4229) 2024-10-25 11:10:30 -07:00
Thomas Brandého
3fba4101e7
convert test_table to use playwright (#4241)
* convert test_table to use playwright

* clean up test
2024-10-25 18:43:24 +02:00
Masen Furer
d85236b9b0
[ENG-3970] When normal pickle fails, try dill (#4239)
* [ENG-3970] When normal pickle fails, try dill

If dill is not installed, suggest that the user `pip install` it.

Fix #4147

* re-lock depenedencies

* Include original pickle error message for better debugging

When the pickling throws a warning and dill is not installed, include the
original pickle error.

Add a test case for an object that even dill cannot pickle to ensure error path
is hit as expected.

* py3.9 compatibility
2024-10-24 16:19:32 -07:00
Thomas Brandého
cba6993247
test for stateless apps (#3816)
* test for stateless apps

* add playwright to dev dependencies

* fix docstring

* fix install of playwright in CI

* fix install again

* add allowed license

* add retry on running integrations step

* another attempt to fix licensing issue

* update timeout duration for retry

* fix timeout workflows

* remove dep changes

* remove outdated diff

* fix scope in new test and workflow for appharness

* run playwright tests last
2024-10-24 14:53:42 -07:00
Khaleel Al-Adhami
c3848d0db4
use $ syntax (#4237)
* use $ syntax

* missing test case change

* try being a little smart

* improve merge imports logic

* add public as well

* oops missed that one

* last one there
2024-10-24 14:34:39 -07:00
Masen Furer
2e703f7aaa
Fix 'enter_key_submit=True' on 'rx.text_area' by carrying custom_code on debounce (#4142)
* debounce: handle custom code from child component

Include _get_all_hooks when rendering the child element, instead of just
internal hooks.

* textarea: handle special behaviors during `create`

Move special behavior handling to `create` classmethod to allow carrying of
added props when wrapped in debounce, which does not call `_render` on the
child component.
2024-10-24 14:34:23 -07:00
benedikt-bartscher
c0ed8b7d91
fix: async default setters break setvar (#4169)
* fix: async default setters break setvar

* fix unit test
2024-10-24 14:27:35 -07:00
Khaleel Al-Adhami
d0c1eb7488
fix inverted alembic file check (#4238) 2024-10-24 14:26:31 -07:00
benedikt-bartscher
9d29e7f3ee
fix and test bug in config env loading (#4205)
* fix and test bug in config env loading

* streamline env var interpretation with @adhami3310

* improve error messages, fix invalid value for TELEMETRY_ENABLED

* just a small hint

* ruffing

* fix typo from review
2024-10-24 10:27:23 -07:00
Thomas Brandého
0bf778e270
make python-dotenv optional (#4222)
* python-dotenv is optional

* add type ignore
2024-10-23 16:29:50 -07:00
Masen Furer
24cef3d4b6
[ENG-3989] Ensure non-serialized states are present in StateManagerDisk (#4230)
If a non-root state was serialized, but its substates were not, then these
would not be populated when reloading the pickled state, because only substates
from the root were being populated with fresh versions.

Now, capture the substates from all fresh states and apply them to the
deserialized state for each substate to ensure that the entire state tree has
all substates instantiated after deserializing, even substates that were never
serialized originally.
2024-10-23 16:09:02 -07:00
Khaleel Al-Adhami
fafad0e3d5
add additional typing for calling events (#4218)
* add additional typing for calling events

* simplify some code

* self isn't with us

* fix pyi
2024-10-23 15:12:02 -07:00
Khaleel Al-Adhami
3eab2b6e7d
implement rx dynamic (#4195)
* implement rx dynamic

* dang it darglint

* add custom type
2024-10-22 14:27:04 -07:00
Khaleel Al-Adhami
a65fc2e90b
Add on progress typing to react player (#4211)
* add on progress typing to react player

* fix pyi file

* have the pyi here as well

* more pyi changes

* fix imports

* run pyi

* for some reason it want event on three lines no clue why

* simplify case for when type is in the same module

* run pyi

* remove last missing type for datadisplay
2024-10-22 13:09:14 -07:00
Simon Young
227fb2cb75
HOS-93: add support for .env file (#4219)
* HOS-93: add support for .env file

* HOS-93: remove stray print

* HOS-93: poetry lock

* HOS-93: update comment

---------

Co-authored-by: simon <simon@reflex.dev>
2024-10-22 12:37:17 -07:00
Thomas Brandého
13591793de
move client storage classes to their own file (#4216)
* move client storage classes to their own file

* fix 3.9 annotations
2024-10-22 21:17:31 +02:00
Thomas Brandého
0aca89781f
bump ruff to 0.7.0 (#4213)
* bump ruff to 0.7.0

* ignore SIM115 and reverse change for it
2024-10-22 20:48:47 +02:00
Simon Young
993bfaef2d
HOS-92: added max-request support to gunicorn (#4217)
Co-authored-by: simon <simon@reflex.dev>
2024-10-22 11:32:13 -07:00
Elijah Ahianyo
d63b3a2bce
[ENG-3848][ENG-3861]Shiki Code block Experimental (#4030)
* Shiki Code block Experimental

* refactor

* update code

* remove console.log

* add transformers to namespace

* some validations

* fix components paths

* fix ruff

* add a high-level component

* fix mapping

* fix mapping

* python 3.9+

* see if this fixes the tests

* fix pyi and annotations

* minimal update of theme and language map

* add hack for reflex-web/flexdown

* unit test file commit

* [ENG-3895] [ENG-3896] Update styling for shiki code block

* strip transformer triggers

* minor refactor

* linter

* fix pyright

* pyi fix

* add unit tests

* sneaky pyright ignore

* the transformer trigger regex should remove the language comment character

* minor refactor

* fix silly mistake

* component mapping in markdown should use the first child for codeblock

* use ternary operator in numbers.py, move code block args to class for docs discoverability

* precommit

* pyright fix

* remove id on copy button animation

* pyright fix for real

* pyi fix

* pyi fix fr

* check if svg exists

* copy event chain

* do a concatenation instead of first child

* added comment

---------

Co-authored-by: Carlos <cutillascarlos@gmail.com>
2024-10-22 17:01:34 +00:00
Khaleel Al-Adhami
c103ab5e28
Add type hinting to dataeditor events (#4210) 2024-10-21 18:53:51 -07:00
Khaleel Al-Adhami
3ab750fecd
add event types to suneditor (#4209) 2024-10-21 18:17:27 -07:00
Khaleel Al-Adhami
45959881ac
add type hinting to error boundary (#4182)
* add type hinting to error boundary

* remove logFrontendError

* fix other calls to handle_frontend_exception
2024-10-21 18:17:06 -07:00
Khaleel Al-Adhami
54ad9f0f4b
make var system expandable (#4175)
* make var system expandable

* use old syntax

* remove newer features

* that's a weird error

* remove unnecessary error message

* remove hacky getattr as it's no longer necessary

* improve color handling

* get it right pyright

* dang it darglint

* fix prototype to string

* don't try twice

* adjust test case

* add test for var alpha

* change place of type ignore

* fix json

* add name to custom var operation

* don't delete that you silly

* change logic

* remove extra word
2024-10-21 17:05:13 -07:00
Khaleel Al-Adhami
f39e8c9667
move all environment variables to the same place (#4192)
* move all environment variables to the same place

* reorder things around

* move more variables to environment

* remove cyclical imports

* forgot default value for field

* for some reason type hints aren't being interpreted

* put the field type *before* not after

* make it get

* move a bit more

* add more fields

* move reflex dir

* add return

* put things somewhere else

* add custom error
2024-10-21 13:28:55 -07:00
Masen Furer
c05da488f9
Raise TypeError when ComputedVar.__init__ gets bad kwargs (#4199)
It's easy to mis-spell `rx.var(cached=True)` instead of `rx.var(cache=True)`,
and in 0.6.3, this doesn't actual raise an error... the bad value is silently
discarded and the var is NOT marked as being cached.
2024-10-21 12:56:56 -07:00
Thomas Brandého
7168b42bab
versions bump before 0.6.4 (#4208) 2024-10-21 12:56:36 -07:00
benedikt-bartscher
7560bf6429
allow setting run mode via env, add helpers to determine it (#4168) 2024-10-21 12:26:09 -07:00
Khaleel Al-Adhami
fcc97b0402
upgrade node to latest lts (#4191) 2024-10-21 12:11:00 -07:00
Masen Furer
6cb87a812f
Fix runtime error on python 3.11.0 (#4197)
All generic types present in a Union must be parametrized on 3.11.0 if any
other generic types in the union are parametrized.

This appears to be a bug in 3.11.0, as the behavior is not observed in 3.11.1
or 3.10; fixing here as this is technically more correct anyway and avoids a
crash.
2024-10-17 19:21:43 -07:00
Masen Furer
330c280c78
When REDIS_URL is set, use redis, regardless of config preference. (#4196)
We might change this down the road, but we don't want to introduce a breaking
change at this time.
2024-10-17 16:54:36 -07:00
Masen Furer
e14c79d57d
[ENG-3954] Treat ArrayVar.foreach index as int (#4193)
* [ENG-3954] Treat ArrayVar.foreach index as int

* foreach: convert return value to a Var

When the value returned from the foreach is not hashable (mutable type), then
it will raise an exception if it is not first converted to a LiteralVar.
2024-10-17 16:16:24 -07:00
Khaleel Al-Adhami
101fb1b540
check for none before returning which (#4187) 2024-10-16 15:21:47 -07:00
Khaleel Al-Adhami
35810fe1bd
use larger or equal for node version check (#4189) 2024-10-16 15:20:51 -07:00
Khaleel Al-Adhami
d8ea2fc795
fix pyi for untyped event handlers (#4186)
* fix pyi for untyped event handlers

* no more empty lambdas
2024-10-16 13:39:49 -07:00
Alek Petuskey
13c9094343
Remove demo command (#4176)
* Remove demo command

* Format

---------

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
2024-10-16 11:35:56 -07:00
Masen Furer
da9d7eabdd
Arbitrary arg access two levels deep for untyped handler (#4180)
* Arbitrary arg access two levels deep for untyped handler

Provide drop-in compatibility with existing component wrapping code
that was accessing attributes on the default handler arg type.

* py3.9 compat
2024-10-16 11:35:27 -07:00
Masen Furer
4422515f4b
LiteralEventChainVar becomes an ArgsFunctionOperation (#4174)
* LiteralEventChainVar becomes an ArgsFunctionOperation

Instead of using the ArgsFunctionOperation to create the string representation
of the _js_expr, make the identity of the var an ArgsFunctionOperation so the
_args_names and _return_expr remain accessible.

Rely on the default behavior of ArgsFunctionOperation to create the
_cached_var_name / _js_expr value.

This allows the compat shim in `format_event_chain` to remain functional, as it
does special handling for ArgsFunctionOperation to retain the previous behavior
of that function (this was a regression introduced in 0.6.2).

* _var_type is EventChain; fix parent class order

* Re-fix LiteralEventChainVar inheritence list w/ comment

* [ENG-3942] LiteralEventVar becomes VarCallOperation

instead of using `.call` when constructing the `_js_expr`, have the identity of
a LiteralEventVar as a VarCallOperation to take advantage of the _var_data
carrying.

* add event overlords

* EventCallback descriptor always returns EventSpec from class

Relax actual `__get__` definition to support the multitude of overloads

* test case for event related vars carrying _var_data

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-10-16 11:35:09 -07:00
Khaleel Al-Adhami
7565ae15ef
disk is memory is disk (#4185) 2024-10-16 11:31:05 -07:00
Khaleel Al-Adhami
2018be8e08
only treat dict object vars as key value mapping (#4177) 2024-10-15 12:21:03 -07:00
Masen Furer
5b802c2c9e
bump version to 0.6.4dev1 for further development (#4178) 2024-10-15 10:54:14 -07:00
Masen Furer
3a14025999
pin AppHarness tests to ubuntu-22.04 runner (#4173) 2024-10-14 15:36:30 -07:00
Manoj Bhat
d6797a1f1d
Change the defalut direction of radio group (#4070). (#4146)
- The default direction of radio groups is column.
- Since most use cases are horizontal, change the default direction from
  column to row.
2024-10-14 08:47:38 -07:00
Masen Furer
1d268f8b13
Support aria and data props (#4149)
* Support aria and data props

* Fix busted docstring

* Ignore special_attributes logic for defined props

* simplify special attribute checking logic

avoid special cases in the special case handling code 🙄
2024-10-14 08:45:25 -07:00
Khaleel Al-Adhami
b2d2719f90
add type hinting to events (#4145)
* add type hinting to events

* fix pyi

* make it a list

* add on change

* dang it darglintz

* add future annotations

* add try except becuse i hate this

* add check for class

* aaaa

* sometimes you need to make hard decisions

* ono

* i hate unions

* add rx event

* move stuff around

* maybe

* special case osmething

* i don't need no test

* remove stray print

Co-authored-by: Masen Furer <m_github@0x26.net>

* remove another stray print

Co-authored-by: Masen Furer <m_github@0x26.net>

* add rx event

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-10-14 08:44:31 -07:00
Khaleel Al-Adhami
b1d449897a
unionize base var fields types (#4153)
* unionize base var fields types

* add tests

* fix union types for vars (#4152)

* remove 3.11 special casing

* special case on version

* fix old versions of python

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-10-11 17:27:15 -07:00
benedikt-bartscher
0889276e24
Do not auto-determine generic args if already supplied (#4148)
* add failing test for figure_out_type

* do not auto-determine generic args if already supplied

* move has_args to utils.types, add tests for it
2024-10-11 17:08:39 -07:00
Masen Furer
736b2a6ea9
Handle rx.State subclasses defined in function (#4129)
* Handle rx.State subclasses defined in function

* create a new container module: `reflex.istate.dynamic` to save references to
  dynamically generated substates.
* for substates with `<locals>` in the name, copy these to the container module
  and update the name to avoid duplication.
* add test for "poor man" ComponentState

Fix #4128

* test_state: disable local def handling for dupe-detection test

* Track the original module and name for type hint evaluation

Also use the original name when checking for the "mangled name" pattern when
doing undeclared Var assignment checking.
2024-10-11 16:51:10 -07:00
Masen Furer
a2862bd102
Allow setting a different invocation function for EventChain (#4160)
In rx.call_script scenario, the EventChain must call `queueEvents` and
`processEvent` instead of `addEvents`, because the former are in scope in the
call_script eval environment where `addEvents` is not.

This is an escape hatch for certain wrapping scenarios.
2024-10-11 16:49:40 -07:00
Khaleel Al-Adhami
0311dae568
only read if it's *not* empty (#4165) 2024-10-11 16:49:01 -07:00
Khaleel Al-Adhami
1eb92fa39b
change bun install link to main (#4164) 2024-10-11 15:51:30 -07:00
Khaleel Al-Adhami
189700ecb3
Change bun link (#4162)
* change bun to download from us

* make it use branch
2024-10-11 15:43:54 -07:00
Khaleel Al-Adhami
210c1ed902
fix union types for vars (#4152) 2024-10-11 11:39:31 -07:00
Carlos
3da1a8d082
default props comment for Axis (#4109)
* default props comment for Axis

* update
2024-10-10 15:10:42 -07:00
Carlos
efd633e76a
default props comment for Pie (#4103) 2024-10-10 15:10:28 -07:00
Carlos
c3d7cd0da1
default props comment for PolarRadiusAxis (#4108)
* default props comment for PolarRadiusAxis

* update
2024-10-10 15:10:11 -07:00
Carlos
ec6990fb71
default props comment for RadialBar (#4105)
* default props comment for RadialBar

* update
2024-10-10 13:04:49 -07:00
Carlos
ee3182a2df
default props comment for Cartesian (#4114)
* default props comment for Cartesian

* add animation events

* update
2024-10-10 13:00:23 -07:00
Carlos
4a314394fd
default props comment for ErrorBar (#4120)
* default props comment for ErrorBar

* union int float

* update
2024-10-10 12:59:38 -07:00
Carlos
132a3d4d1d
default props comment for Funnel (#4119)
* default props comment for Funnel

* update
2024-10-10 12:58:38 -07:00
Carlos
11abaf8055
default props comment for Grid (#4125) 2024-10-10 12:57:46 -07:00
Thomas Brandého
6f586c8b8f
let users pick state manager mode (#4041) 2024-10-10 12:22:35 -07:00
benedikt-bartscher
1aed39a848
catch ValueError("I/O operation on closed file.") if frontend crashes (#4150) 2024-10-10 12:18:57 -07:00
Khaleel Al-Adhami
8ec3cf6157
remove dictify from state dict (#4141) 2024-10-10 12:18:18 -07:00
abulvenz
87648af3ee
fix: Determine var type from value. (#4143) 2024-10-09 17:33:34 -07:00
benedikt-bartscher
7a971e5842
fix docstring (#4140) 2024-10-09 13:42:44 -07:00
Khaleel Al-Adhami
91ab8ac574
Remove wrong event handlers (#4136)
* remove wrong target value

* add keyboard event

* simplify empty ones

* remove events from text_area

* empty tuples are empty bruh

* dangit darglint
2024-10-09 13:25:41 -07:00
Thomas Brandého
60b6d4e7f2
only run macOS job on merge (#4139)
* update workflow

* skip more in unit tests

* try something else to prevent adding macos job to pool

* exclude too much

* fix units-text with macOS excluded

* also drop macOS job in integration tests

* readd macos job separately to only run on merge
2024-10-09 13:24:03 -07:00
ruhz3
f3b8b2e336
First use environment variable as npm registry (#4082)
* First use environment variable as npm registry

* use NPM_CONFIG_REGISTRY as env variable

---------

Co-authored-by: 류형주/인공지능팀 <hyungju.ryu@ahnlab.com>
2024-10-09 11:36:33 -07:00
Nguyễn Minh Phú
0e7627d1c4
Add Vietnamese README docs (#4138) 2024-10-09 08:58:08 -07:00
Carlos
ffcf87d587
default props comment for Radar (#4104) 2024-10-08 17:00:42 -07:00
Carlos
535c8f904d
default props comment for funnelchart (#4097) 2024-10-08 16:54:45 -07:00
Carlos
c244418aaa
default props comment for Reference (#4121) 2024-10-08 16:51:36 -07:00
Carlos
4a3fd592e9
default props comment for PolarGrid (#4107) 2024-10-08 16:51:26 -07:00
Carlos
ce8695c14c
default props comment for categoricalchartbase (#4091) 2024-10-08 16:45:43 -07:00
Carlos
65c174ed78
areachart default value for base_value (#4090) 2024-10-08 16:45:29 -07:00
Carlos
240b12a7f3
default props comment for composedchart (#4093) 2024-10-08 16:45:18 -07:00
Carlos
068b3bab42
default props comment for barchart (#4092) 2024-10-08 16:42:41 -07:00
Carlos
1bf8c7728e
default props comment for radialbarchart (#4095) 2024-10-08 16:42:32 -07:00
Carlos
32a3cb61c1
default props comment for radarchart (#4094) 2024-10-08 16:41:40 -07:00
Carlos
b0de28208f
default props comment for scatterchart (#4096) 2024-10-08 16:30:34 -07:00
Carlos
2f8205216a
default props comment for ResponsiveContainer (#4099) 2024-10-08 16:28:15 -07:00
Carlos
9f11b83fa9
default props comment for treemap (#4098) 2024-10-08 16:25:47 -07:00
Carlos
f05da7cead
default props comment for LabelList (#4102) 2024-10-08 16:17:59 -07:00
Carlos
2718cb51eb
default props comment for PolarAgnleAxis (#4106) 2024-10-08 16:17:14 -07:00
Carlos
e633cd0385
default props comment for Legend (#4100) 2024-10-08 16:11:32 -07:00
Carlos
9c7de9b189
default props comment for XAxis (#4110)
* default props comment for XAxis

* axis id
2024-10-08 16:09:03 -07:00
Carlos
19df34d941
default props comment for YAxis (#4111)
* default props comment for YAxis

* axis id
2024-10-08 16:07:24 -07:00
Carlos
c3b7caaf13
default props comment for ZAxis (#4112) 2024-10-08 16:06:05 -07:00
Carlos
4843081089
default props comment for Brush (#4113) 2024-10-08 16:05:22 -07:00
Carlos
7b88c54d13
default props comment for Bar (#4116) 2024-10-08 15:58:22 -07:00
Carlos
2652a04be8
default props comment for Line (#4117) 2024-10-08 15:57:11 -07:00
Carlos
abf0329cd9
default props comment for Area (#4115) 2024-10-08 15:56:11 -07:00
Carlos
be980c6b1e
default props comment for Scatter (#4118) 2024-10-08 15:54:42 -07:00
Carlos
567cf7ea38
default props comment for ReferenceArea (#4124) 2024-10-08 15:49:30 -07:00
Khaleel Al-Adhami
c619c72211
use system npm when REFLEX_USE_SYSTEM_NODE is passed (#4133) 2024-10-08 13:25:49 -07:00
Carlos
cb4ff24dc0
default props comment for ReferenceLine (#4122) 2024-10-08 12:37:10 -07:00
Carlos
4982b450fe
default props comment for CartesianGrid (#4126) 2024-10-08 12:36:27 -07:00
Carlos
02d4428e39
default props comment for CartesianAxis (#4127) 2024-10-08 12:36:19 -07:00
Thomas Brandého
5e3cfecdea
fix custom component init (#4123) 2024-10-08 09:15:56 -07:00
Masen Furer
876426c581
test_dynamic_routes: log on_loads and poll for 60 seconds on order (#4089)
Assert on `list(...order)` so the error message prints actual value instead of
MutableProxy's repr.

Not sure if this fixes it...
2024-10-08 09:14:35 -07:00
Masen Furer
37508676cf
Revert Markdown-related frontend dep bumps (#4088)
* Revert markdown version bumps

* Ignore markdown related dependencies (these are pinned now)
2024-10-08 16:16:54 +02:00
Khaleel Al-Adhami
af83161fed
reset backend vars in state.reset() (#4087) 2024-10-07 15:04:01 -07:00
Khaleel Al-Adhami
8663d4f978
[ENG-3749] type safe vars (#4066)
* type safe vars

* fix behavior for dict and list
2024-10-07 14:59:02 -07:00
Masen Furer
7529bb0c64
[ENG-2287] Avoid fetching same state from redis multiple times (#4055)
* Avoid fetching substates multiple times

In the presence of computed vars, substates may be cached more than once.

* Consolidate logic in StateManagerRedis.get_state

* Suppress StateSchemaMismatchError and create a new state instance.

If the serialized state's schema does not match the current corresponding state
schema, then we have to create a new instance.
2024-10-07 14:58:41 -07:00
Thomas Brandého
0e99ce91c1
update ruff to latest version (#4081)
* update ruff to latest version

* fix pyi
2024-10-07 23:52:36 +02:00
Khaleel Al-Adhami
bec73109d6
upgrade default node to current lts (#4086) 2024-10-07 13:24:23 -07:00
Khaleel Al-Adhami
c7c830de80
fail safely when pickling (#4085)
* fail safely when pickling

* why did i do that
2024-10-07 11:59:33 -07:00
Thomas Brandého
59dd54c049
add workflow to check dependencies on release branch (#4050)
* add workflow to check dependencies on release branch

* rename action to follow convention of other actions

* update workflow

* bump poetry version

* relock deps

* update check to ignore pyright and ruff

* oops, you saw nothing

* split dep check in two job

* fix frontend dep check

* fix stuff

* hmm yeah

* nope nope nope

* sigh

* bump js versions for some packages

* fix some warnings in tests

* fix tests

* try some options

* try to set asyncio policy

* debug dep check

* fix attempt for backend dep

* clean up output for backend check

* run bun outdated on reflex-web to catch most of the packages

* fix python version

* fix python version

* add missing env

* fix bun command

* fix workdir of frontend check

* update packages version

* up-pin plotly.js version

* add debug ouput

* clean frontend dep check output

* fix output

* fix async tests for redis

* relock poetry.lock

* Non-async functions do not need pytest_asyncio.fixture

* test_state: close StateManagerRedis connection in test to avoid warning

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-10-07 20:57:02 +02:00
Khaleel Al-Adhami
7cd5c904cb
misc var improvements (#4068) 2024-10-07 09:37:44 -07:00
Khaleel Al-Adhami
47230198bb
bundle next link in window (#4064) 2024-10-07 09:36:22 -07:00
Masen Furer
edd17208c0
Reduce pickle size (#4063)
* Only serialize base vars
* Never serialize router/router_data in substates
* Hash the schema to reduce serialized size
* lru_cache the schema to avoid recomputing it
2024-10-07 09:34:36 -07:00
Masen Furer
5c0518053d
Get default for backend var defined in mixin (#4060)
* Get default for backend var defined in mixin

If the backend var is defined in a mixin class, it won't appear in
`cls.__dict__`, but the value is still retrievable via `getattr` on `cls`.
Prefer to use the actual defined default before using
`Var.get_default_value()`.

If `Var.get_default_value()` fails, set the default to `None` such that the
backend var still gets recognized as a backend var when it is used on `self`.

----

Update test_component_state to include backend vars

Extra coverage for backend vars with and without defaults, defined in a
ComponentState/mixin class.

* fix integration test
2024-10-07 09:33:44 -07:00
Masen Furer
aa69234b76
Optimize StateManagerDisk (#4056)
* Simplify StateManagerDisk implementation

* Act more like the memory state manager and only track the root state in self.states
* .load_state always loads a single state or returns None
* .populate_states is the new entry point in loading from disk and it only occurs
  when the root state is not known
* much fast

* StateManagerDisk now acts much more like StateManagerMemory

Treat StateManagerDisk like StateManagerMemory for AppHarness

* Handle root_state deserialized from disk

In this case, we need to initialize the whole state tree, so any non-persistent
states will still get default values, whereas on-disk states will overwrite the
defaults.

* Cache root_state under client_token for StateManagerMemory compatibility

Mainly this just makes it easier for us to write tests that work against either
Disk or Memory state managers.
2024-10-07 09:33:16 -07:00
Thomas Brandého
1f3be6340c
catch CancelledError in lifespan hack for windows (#4083) 2024-10-07 09:27:36 -07:00
Khaleel Al-Adhami
12b81ad754
convert literal type to its variants (#4062) 2024-10-04 13:56:25 -07:00
Masen Furer
9b5a36814a
bump version to 0.6.3dev1 (#4061) 2024-10-04 12:27:52 -07:00
Masen Furer
d77b900bd7
[ENG-3867] Garden Variety Pickle (#4054)
* Use regular `pickle` module from stdlib

* Avoid recreating the rx.State tree for every `get_state`

* Remove dill dependency

* relock deps
2024-10-03 19:19:06 -07:00
Khaleel Al-Adhami
fafdeb892e
Include emotion inside of dynamic components (#4052)
* bundle chakra in window for CSR

* remove repeated chakra ui reference

* use dynamically generated libraries

* remove js from it

* include emotion react for dynamic components

* make code more readable

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

* jsx yea

* what

---------

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
2024-10-03 15:58:42 -07:00
Khaleel Al-Adhami
0f8630fb2d
remove var operation error (#4053)
* remove var operation error

* dang it darglint
2024-10-03 15:58:04 -07:00
Khaleel Al-Adhami
73e8a4e0ab
support eventspec/eventchain in var operations (#4038) 2024-10-03 15:33:51 -07:00
Khaleel Al-Adhami
ad0827c59c
bundle chakra in window for CSR (#4042)
* bundle chakra in window for CSR

* remove repeated chakra ui reference

* use dynamically generated libraries

* remove js from it
2024-10-03 14:25:21 -07:00
Masen Furer
a66e0f2e11
[ENG-3870] rx.call_script with f-string var produces incorrect code (#4039)
* Add additional test cases for rx.call_script

Include internal vars inside an f-string to be properly rendered on the backend
and frontend.

* [ENG-3870] rx.call_script with f-string var produces incorrect code

Avoid casting javascript code with embedded Var as LiteralStringVar

There are two cases that need to be handled:

1. The javascript code contains Vars with VarData, these can only be evaluated
   in the component context, since they may use hooks. Vars with VarData cannot be
   used from the backend. In this case, we cast the given code as a raw js
   expression and include the extracted VarData.

2. The javascript code has no VarData. In this case, we pass the code as the
   raw js expression and cast to a python str to get a js literal string to eval.

* use VarData.__bool__ instead of `is None`
2024-10-03 14:18:53 -07:00
Thomas Brandého
40f1880932
move router dataclasses in their own file (#4044) 2024-10-03 14:18:28 -07:00
Khaleel Al-Adhami
56709a210b
add of_type to _evaluate (#4051)
* add of_type to _evaluate

* get it right pyright
2024-10-03 13:01:19 -07:00
Khaleel Al-Adhami
27bb7179d6
default should be warning for subprocesses not info (#4049) 2024-10-03 12:24:56 -07:00
Elijah Ahianyo
4b3d056212
[ENG-3476] Setting State Vars that are not defined should raise an error (#4007) 2024-10-03 10:35:34 -07:00
Elijah Ahianyo
12d73e4167
Track the last reflex run time (#4045) 2024-10-03 09:48:50 -07:00
Thomas Brandého
3f51943162
use pathlib as much as possible (#3967)
* use pathlib as much as possible

* fixstuff

* break locally to unbreak in CI 🤷

* add type on env

* debug attempt 1

* debugged

* oops, there is the actual fix

* fix 3.9 compat
2024-10-03 17:50:39 +02:00
Thomas Brandého
f3be9a3305
fix granian message (#4037) 2024-10-03 15:04:44 +02:00
Khaleel Al-Adhami
6a9f83cc2d
set loglevel to info with hosting cli (#4043)
* set loglevel to info with hosting cli

* reduce reused logic
2024-10-02 18:04:04 -07:00
Masen Furer
c08720ed1a
Use an equality check instead of startswith (#4024) 2024-10-01 15:23:35 -07:00
Simon Young
e96b4bf42e
a friendly little helper (#4021)
* a friendly little helper

* addressing comments

* update comment

---------

Co-authored-by: simon <simon@reflex.dev>
2024-10-01 14:32:05 -07:00
Masen Furer
9c3cc0cfa6
bump version to 0.6.2dev1 (#4025)
For further development against the version that will become 0.6.2
2024-10-01 12:34:28 -07:00
ChinoUkaegbu
bd71c8e6c9
feat: Add support for missing SVGs (#3962) 2024-10-01 09:24:26 -07:00
Khaleel Al-Adhami
9719f5d57e
use literal var instead of serialize for toast props (#4027) 2024-09-29 12:08:56 -07:00
Thomas Brandého
23e979717f
remove all runtime asserts (#4019)
* remove all runtime asserts

* Update reflex/testing.py

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-09-27 17:25:22 -07:00
Khaleel Al-Adhami
62021b0b40
implement _evaluate in state (#4018)
* implement _evaluate in state

* add warning

* use typing_extension

* add integration test
2024-09-27 16:58:20 -07:00
Thomas Brandého
1b3422dab6
improve lifespan typecheck and debug (#4014)
* add lifespan debug statement

* improve some of the logic for lifespan tasks

* fix partial name with update_wrapper
2024-09-27 16:17:30 -07:00
Masen Furer
9ca5d4a095
Track backend-only vars that are declared without a default value (#4016)
* Track backend-only vars that are declared without a default value

Without this provision, declared backend vars can be accidentally shared among
all states if a mutable value is assigned to the class attribute.

* add test case for no default backend var
2024-09-27 12:04:43 -07:00
Khaleel Al-Adhami
eea5dc1918
change loglevel and fix granian on linux (#4012)
* change loglevel and fix it on linux

* run precommit

* fix that as well
2024-09-26 21:54:03 -07:00
Masen Furer
ae0f3f820e
Handle bool cast for optional NumberVar (#4010)
* Handle bool cast for optional NumberVar

If the _var_type is optional, then also check that the value is not None

* boolify the result of `and_operation`

* flip order to be more semantically pure

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-09-26 21:52:31 -07:00
Thomas Brandého
299f842756
add env var to enable using system node and bun (#4006)
* add env var to enable using system node and bun

* fix test to use env var
2024-09-26 16:12:12 -07:00
Khaleel Al-Adhami
0ab161c119
remove format_state and override behavior for bare (#3979)
* remove format_state and override behavior for bare

* pass the test cases

* only do one level of dicting dataclasses

* remove dict and replace list with set

* delete unnecessary serialize calls

* remove serialize for mutable proxy

* dang it darglint
2024-09-26 16:00:28 -07:00
Khaleel Al-Adhami
70bd88c682
serialize default value for disk state manager (#4008) 2024-09-26 13:59:17 -07:00
LeoH
60276cf1ff
EventFnArgMismatch fix to support defaults args (#4004)
* EventFnArgMismatch fix to support defaults args

* fixing type hint and docstring raises

* enforce stronger type checking

* unwrap var annotations :(

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-09-26 13:56:53 -07:00
Khaleel Al-Adhami
54c7b5a261
disable prose by default for rx.html (#4001)
* disable prose by default for rx.html

* remove styled

* put that on one line
2024-09-26 13:47:05 -07:00
Thomas Brandého
130bcf96ca
default on_submit in form set to prevent_default (#4005)
* default submit forms set to prevent_default

* fix tests
2024-09-26 11:56:59 -07:00
Masen Furer
25016f5e27
Update markdown component map to use new rx.code_block.theme enum (#3996)
* Update markdown component map to use new rx.code_block.theme enum

* change var to theme

* give the types some attention instead of ignoring them

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-09-26 11:04:35 -07:00
Thomas Brandého
3f538865b5
reorganize all tests in a single top folder (#3981)
* lift node version restraint to allow more recent version if already installed

* add node test for latest version

* change python version

* use purple for debug logs

* update workflow

* add playwright dev dependency

* update workflow

* change test

* oops

* improve test

* update test

* fix tests

* mv units tests to a subfolder

* reorganize tests

* fix install

* update test_state

* revert node changes and only keep new tests organization

* move integration tests in tests/integration

* fix integration workflow

* fix dockerfile workflow

* fix dockerfile workflow 2

* fix shared_state
2024-09-26 01:22:52 +02:00
Thomas Brandého
b07fba72e9
add missing message when running in backend_only (#4002)
* add missing message when running in backend_only

* actually pass loglevel to backend_cmd
2024-09-26 00:57:08 +02:00
Khaleel Al-Adhami
9d8b737b1a
hash the state file name (#4000)
* hash the state file name

* forgot to digest my food oop
2024-09-25 13:11:04 -07:00
Masen Furer
e1538b75f8
bump to 0.6.1 for further dev (#3995)
* bump version to 0.6.1dev1

* bump reflex-chakra requirement to 0.6.0

* update poetry file

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-09-25 11:31:45 -07:00
Khaleel Al-Adhami
74d1c47ce2
allow classname to be state vars (#3991)
* allow classname to be state vars

* simplify join with all literal string vars

* add test case and avoid concat var operation if it's not necessary

* remove silly print statement

* simplify case where there's no var

* don't automatically do class name str to literal var
2024-09-25 09:57:29 -07:00
Khaleel Al-Adhami
982c43d595
use bundled radix ui for dynamic components (#3993) 2024-09-25 09:57:16 -07:00
Thomas Brandého
3eeb0bde9c
bump nextjs version (#3992) 2024-09-25 09:56:15 -07:00
Khaleel Al-Adhami
fc5d352431
add basic integration test for dynamic components (#3990)
* add basic integration test

* fix docstrings

* dang it darglint
2024-09-25 09:55:16 -07:00
Khaleel Al-Adhami
5e738fd62b
don't camel case keys of dicts in style (#3982)
* don't camel case keys of dicts in style

* change tests to fit the code 😎

* respect objectvars as true dicts
2024-09-24 17:38:49 -07:00
Thomas Brandého
46be46d6ea
allow link as metatags (#3980)
* allow link as metatags

* remove stray print & fix nit
2024-09-24 17:38:12 -07:00
Thomas Brandého
001b8c4222
can run with granian by setting REFLEX_USE_GRANIAN var (#3919)
* can run with granian by setting REFLEX_USE_GRANIAN var

* granian also useable for prod mode

* adjust reload paths for granian

* move uvicorn / granian logic to their own function

* fix prod mode
2024-09-24 17:36:58 -07:00
Thomas Brandého
d0ad5cd15e
use svg elements instead of raw html for logo (#3978)
* use svg elements instead of raw html for logo

* avoid duplication
2024-09-24 17:34:41 -07:00
Thomas Brandého
4e4d36a867
re add removed method with better behaviour and tests (#3986) 2024-09-24 23:29:56 +02:00
Andrew Davies
2c4310d9ff
Use tailwind typography plugin by default (#3593)
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-09-23 18:18:05 -07:00
Masen Furer
2883e541a9
Bring back py3.9 support with a deprecation warning. (#3976)
* Revert "ruff formatting to unbreak `main` CI (#3964)"

This reverts commit f9be184b86.

* Revert "bump python>=3.10 for 0.6.0 (#3956)"

This reverts commit fe1833c5e1.

* drop python3.8 support

* relock dependencies

* Raise warning when < py310 is used

* Move python version check to reflex version check function

Avoid spammy deprecation warnings by only emitting warning once per project,
per reflex version, per reinit.

* Remove other references to python3.8
2024-09-23 18:15:16 -07:00
Khaleel Al-Adhami
00d995d971
[ENG-3833] handle object in is bool (#3974)
* handle object in is bool

* use if statements
2024-09-23 18:14:28 -07:00
Khaleel Al-Adhami
a5ad5203df
suggest bool() for wrong values (#3975) 2024-09-23 18:13:55 -07:00
Khaleel Al-Adhami
47c9938d95
use is true for bool var (#3973) 2024-09-23 16:36:58 -07:00
Khaleel Al-Adhami
ee3b0e614c
fix set value logix for client state (#3966) 2024-09-23 12:40:14 -07:00
Thomas Brandého
61332fdba1
add some more tests (#3965) 2024-09-22 14:44:44 -07:00
Elijah Ahianyo
afd52a87dd
Make reflex init --ai use light mode (#3963) 2024-09-22 14:44:16 -07:00
Masen Furer
f9be184b86
ruff formatting to unbreak main CI (#3964) 2024-09-20 20:01:57 +02:00
Thomas Brandého
fe1833c5e1
bump python>=3.10 for 0.6.0 (#3956) 2024-09-20 09:52:29 -07:00
Thomas Brandého
456672149b
use current version as default for new custom components (#3957) 2024-09-19 19:08:23 -07:00
Masen Furer
d4cd512144
Add shim for format_event_chain (#3958)
Allow `format_event_chain` to continue working until 0.7.0 to allow third party
component wraps to adapt.
2024-09-19 19:08:00 -07:00
Khaleel Al-Adhami
a5d73654fc
use serializer before serializing base yourself (#3960) 2024-09-19 19:07:09 -07:00
Masen Furer
bca49d3537
Component as Var type (#3732)
* [WiP] Support UI components returned from a computed var

* Get rid of nasty react hooks warning

* include @babel/standalone in the base to avoid CDN

* put window variables behind an object

* use jsx

* implement the thing

* cleanup dead test code (#3909)

* override dict in propsbase to use camelCase (#3910)

* override dict in propsbase to use camelCase

* fix underscore in dict

* dang it darglint

* [REF-3562][REF-3563] Replace chakra usage (#3872)

* [ENG-3717] [flexgen] Initialize app from refactored code (#3918)

* Remove Pydantic from some classes (#3907)

* half of the way there

* add dataclass support

* Forbid Computed var shadowing (#3843)

* get it right pyright

* fix unit tests

* rip out more pydantic

* fix weird issues with merge_imports

* add missing docstring

* make special props a list instead of a set

* fix moment pyi

* actually ignore the runtime error

* it's ruff out there

---------

Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>

* Merging

* fixss

* fix field_name

* always import react

* move func to file

* do some weird things

* it's really ruff out there

* add docs

* how does this work

* dang it darglint

* fix the silly

* don't remove computed guy

* silly goose, don't ignore var types :D

* update code

* put f string on one line

* make it deprecated instead of outright killing it

* i hate it

* add imports from react

* assert it has evalReactComponent

* do things ig

* move get field to global context

* ooops

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>
2024-09-19 19:06:53 -07:00
Thomas Brandého
ef38ac29ea
remove unused badge (#3955) 2024-09-19 11:32:29 -07:00
Masen Furer
5f296eec38
[ENG-3817] deprecate _var_name_unwrapped (instead of removing it) (#3951)
some components and code examples used `_var_name_unwrapped`, so map this
property back to `_js_expr` and deprecate it.
2024-09-18 21:33:50 -07:00
Thomas Brandého
c46d1d9c7e
move the filterwarning to appropriate file (#3952) 2024-09-19 02:21:07 +02:00
Khaleel Al-Adhami
22237658ba
always print passed_type (#3950) 2024-09-18 14:52:18 -07:00
Thomas Brandého
cf69964cd6
add some unit tests for coverage (#3947)
* add some unit tests for coverage

* add test for page decorator

* bump coverage threshold

* check content
2024-09-18 23:44:59 +02:00
Thomas Brandého
44a89b2e87
fix unionize recursion (#3948)
* fix unionize recursion

* merging

---------

Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
2024-09-18 22:50:54 +02:00
Khaleel Al-Adhami
91b50d713e
add special handling for infinity and nan (#3943)
* add special handling for infinity and nan

* use custom exception

* add test for inf and nan
2024-09-18 13:10:32 -07:00
Khaleel Al-Adhami
a8734d7392
add few test cases for bool (#3949)
* add few test cases for bool

* use parametrize

* use a tuple of strings

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-09-18 13:10:18 -07:00
Khaleel Al-Adhami
d81faf7dad
use is true (#3946) 2024-09-18 11:32:47 -07:00
wassaf shahzad
abb884c156
Added fill color for progress (#3926)
* Added fill color for progress

* updated pyi file
2024-09-18 00:08:15 +02:00
Masen Furer
16d3962589
[0.6.0 blocker] state: update inherited_vars and tracking dicts when adding vars (#2822)
* state: update inherited_vars and tracking dicts when adding vars

Ensure that dynamically added vars are accounted for in dependency and
inheritence tree to avoid unrenderable or stale data.

* Regression test for dynamic route args and inherited_vars

* [flexgen] Initialize app from refactored code

Use the new /api/gen/{hash}/refactored endpoint to get refactored reflex code.

* Use _js_expr instead of _var_name
2024-09-17 10:43:33 -07:00
elvis kahoro
5f12243fe4
fix: Adding code comments for segmented control type (#3935)
* fix: Adding code comments for segmented control type

* fix: Manually adding info about type
2024-09-17 02:42:45 +02:00
Thomas Brandého
fe9f3a7088
expose radix primitive progress under rx.radix.primitives.progress (#3930) 2024-09-16 16:36:17 -07:00
Khaleel Al-Adhami
a57095ffe8
use serializer for state update and rework serializers (#3934)
* use serializer for state update and rework serializers

* format
2024-09-16 16:36:01 -07:00
elvis kahoro
37920d6a83
fix: Adding in-line comments for the segmented control: value and (#3933)
on_change
2024-09-16 14:42:28 -07:00
Thomas Brandého
da973299f2
better errors in state.py (#3929) 2024-09-16 23:33:42 +02:00
Thomas Brandého
8260ebb32f
fix template fetch during init (#3932)
* fix template fetch during init

* use masen suggestion
2024-09-16 23:32:10 +02:00
Khaleel Al-Adhami
8328a622a2
Fix string color (#3922) 2024-09-16 11:12:51 -07:00
Khaleel Al-Adhami
085b761f6b
replace old var system with immutable one (#3916)
* delete most references to varr

* [REF-3562][REF-3563] Replace chakra usage (#3872)

* only one mention of var

* delete vars.py why not

* remove reflex.vars

* rename immutable var to var

* rename ivars to vars

* add vars back smh

* ruff

* no more create_safe

* reorder deprecated

* remove raises

* remove all Var.create

* move to new api

* fix unit tests

* fix pyi hopefully

* sort literals

* fix event handler issues

* update poetry

* fix silly issues i'm very silly

* add var_operation_return

* rename immutable to not immutable

* add str type

* it's ruff out there

---------

Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>
2024-09-13 16:01:52 -07:00
Khaleel Al-Adhami
8f937f0417
Remove Pydantic from some classes (#3907)
* half of the way there

* add dataclass support

* Forbid Computed var shadowing (#3843)

* get it right pyright

* fix unit tests

* rip out more pydantic

* fix weird issues with merge_imports

* add missing docstring

* make special props a list instead of a set

* fix moment pyi

* actually ignore the runtime error

* it's ruff out there

---------

Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
2024-09-13 12:53:30 -07:00
Masen Furer
7c25358607
[ENG-3717] [flexgen] Initialize app from refactored code (#3918) 2024-09-13 11:20:25 -07:00
Elijah Ahianyo
625c5302dd
[REF-3562][REF-3563] Replace chakra usage (#3872) 2024-09-12 10:46:42 -07:00
Khaleel Al-Adhami
8657976a6e
override dict in propsbase to use camelCase (#3910)
* override dict in propsbase to use camelCase

* fix underscore in dict

* dang it darglint
2024-09-11 11:47:28 -07:00
benedikt-bartscher
5dcf554bd4
cleanup dead test code (#3909) 2024-09-11 11:15:49 -07:00
benedikt-bartscher
63bf1b8817
Dynamic route vars silently shadow all other vars (#3805)
* fix dynamic route vars silently shadow all other vars

* add test

* fix: allow multiple dynamic routes with the same arg

* add test for multiple dynamic args with the same name

* avoid side-effects with DynamicState tests

* fix dynamic route integration test which shadowed a var

* fix darglint

* refactor to DynamicRouteVar

* old typing stuff again

* from typing_extensions import Self

try to keep typing backward compatible with older releases we support

* Raise a specific exception when encountering dynamic route arg shadowing

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-09-11 09:43:18 -07:00
abulvenz
95631ffdba
Fix type propagation in ToStringOperation (#3895)
* fix: Adding type propagation to ToStringOperation.

* fix: Better naming.

* fix: Added test that fails without the fix.

* Update reflex/ivars/base.py

Co-authored-by: Masen Furer <m_github@0x26.net>

* Retain mutability inside `async with self` block (#3884)

When emitting a state update, restore `_self_mutable` to the value it had
previously so that `yield` in the middle of `async with self` does not result
in an immutable StateProxy.

Fix #3869

* Include child imports in markdown component_map (#3883)

If a component in the markdown component_map contains children components, use
`_get_all_imports` to recursively enumerate them.

Fix #3880

* [REF-3570] Remove deprecated REDIS_URL syntax (#3892)

* fix: Instead of researching the type after dropping it, preserve it.

* Apply suggestions from code review

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-09-11 09:35:19 -07:00
Khaleel Al-Adhami
0810bd843c
remove reference to computed var (#3906) 2024-09-10 13:26:58 -07:00
benedikt-bartscher
d672c643b3
Forbid Computed var shadowing (#3843) 2024-09-10 12:09:35 -07:00
Khaleel Al-Adhami
a5c73ad8e5
Use old serializer system in LiteralVar (#3875)
* use serializer system

* add checks for unsupported operands

* and and or are now supported

* format

* remove unnecessary call to JSON

* put base before rest

* fix failing testcase

* add hinting to get static analysis to complain

* damn

* big changes

* get typeguard from extensions

* please darglint

* dangit darglint

* remove one from vars

* add without data and use it in plotly

* DARGLINT

* change format for special props

* add pyi

* delete instances of Var.create

* modify client state to work

* fixed so much

* remove every Var.create

* delete all basevar stuff

* checkpoint

* fix pyi

* get older python to work

* dangit darglint

* add simple fix to last failing testcase

* remove var name unwrapped and put client state on immutable var

* fix older python

* fox event issues

* change forms pyi

* make test less strict

* use rx state directly

* add typeignore to page_id

* implement foreach

* delete .web states folder silly

* update reflex chakra

* fix issue when on mount or on unmount is not set

* nuke Var

* run pyi

* import immutablevar in critical location

* delete unwrap vars

* bring back array ref

* fix style props in app

* /health endpoint for K8 Liveness and Readiness probes (#3855)

* Added API Endpoint

* Added API Endpoint

* Added Unit Tests

* Added Unit Tests

* main

* Apply suggestions from Code Review

* Fix Ruff Formatting

* Update Socket Events

* Async Functions

* Update find_replace (#3886)

* [REF-3592]Promote `rx.progress` from radix themes (#3878)

* Promote `rx.progress` from radix themes

* fix pyi

* add warning when accessing `rx._x.progress`

* Use correct flexgen backend URL (#3891)

* Remove demo template (#3888)

* gitignore .web (#3885)

* update overflowY in AUTO_HEIGHT_JS from hidden to scroll (#3882)

* Retain mutability inside `async with self` block (#3884)

When emitting a state update, restore `_self_mutable` to the value it had
previously so that `yield` in the middle of `async with self` does not result
in an immutable StateProxy.

Fix #3869

* Include child imports in markdown component_map (#3883)

If a component in the markdown component_map contains children components, use
`_get_all_imports` to recursively enumerate them.

Fix #3880

* [REF-3570] Remove deprecated REDIS_URL syntax (#3892)

* mixin computed vars should only be applied to highest level state (#3833)

* improve state hierarchy validation, drop old testing special case (#3894)

* fix var dependency dicts (#3842)

* Adding array to array pluck operation. (#3868)

* fix initial state without cv fallback (#3670)

* add fragment to foreach (#3877)

* Update docker-example (#3324)

* /health endpoint for K8 Liveness and Readiness probes (#3855)

* Added API Endpoint

* Added API Endpoint

* Added Unit Tests

* Added Unit Tests

* main

* Apply suggestions from Code Review

* Fix Ruff Formatting

* Update Socket Events

* Async Functions

* /health endpoint for K8 Liveness and Readiness probes (#3855)

* Added API Endpoint

* Added API Endpoint

* Added Unit Tests

* Added Unit Tests

* main

* Apply suggestions from Code Review

* Fix Ruff Formatting

* Update Socket Events

* Async Functions

* Merge branch 'main' into use-old-serializer-in-literalvar

* [REF-3570] Remove deprecated REDIS_URL syntax (#3892)

* /health endpoint for K8 Liveness and Readiness probes (#3855)

* Added API Endpoint

* Added API Endpoint

* Added Unit Tests

* Added Unit Tests

* main

* Apply suggestions from Code Review

* Fix Ruff Formatting

* Update Socket Events

* Async Functions

* [REF-3570] Remove deprecated REDIS_URL syntax (#3892)

* remove extra var

Co-authored-by: Masen Furer <m_github@0x26.net>

* resolve typo

* write better doc for var.create

* return var value when we know it's literal var

* fix unit test

* less bloat for ToOperations

* simplify ImmutableComputedVar.__get__ (#3902)

* simplify ImmutableComputedVar.__get__

* ruff it

---------

Co-authored-by: Samarth Bhadane <samarthbhadane119@gmail.com>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>
Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Vishnu Deva <vishnu.deva12@gmail.com>
Co-authored-by: abulvenz <a.eismann@senbax.de>
2024-09-10 11:43:37 -07:00
Khaleel Al-Adhami
fb721e1d12
delete states if it exists on run (#3901)
* delete states if it exists

* simplify ImmutableComputedVar.__get__ (#3902)

* simplify ImmutableComputedVar.__get__

* ruff it

---------

Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
2024-09-09 17:59:40 -07:00
benedikt-bartscher
84ec08616b
simplify ImmutableComputedVar.__get__ (#3902)
* simplify ImmutableComputedVar.__get__

* ruff it
2024-09-09 15:50:40 -07:00
Masen Furer
fa894289d4
Update docker-example (#3324) 2024-09-08 19:21:05 -07:00
Khaleel Al-Adhami
c70cba1e7c
add fragment to foreach (#3877) 2024-09-08 19:14:56 -07:00
benedikt-bartscher
b7c7197f1d
fix initial state without cv fallback (#3670) 2024-09-08 19:10:46 -07:00
abulvenz
21585867b9
Adding array to array pluck operation. (#3868) 2024-09-08 18:36:47 -07:00
benedikt-bartscher
99ffbc8c39
fix var dependency dicts (#3842) 2024-09-08 18:35:47 -07:00
benedikt-bartscher
fd13e559c6
improve state hierarchy validation, drop old testing special case (#3894) 2024-09-08 18:29:37 -07:00
benedikt-bartscher
477e1dece9
mixin computed vars should only be applied to highest level state (#3833) 2024-09-08 18:26:52 -07:00
Masen Furer
43d79d3a24
[REF-3570] Remove deprecated REDIS_URL syntax (#3892) 2024-09-05 14:37:07 -07:00
Masen Furer
cbe532cfc5
Include child imports in markdown component_map (#3883)
If a component in the markdown component_map contains children components, use
`_get_all_imports` to recursively enumerate them.

Fix #3880
2024-09-05 14:36:53 -07:00
Masen Furer
6308eb6665
Retain mutability inside async with self block (#3884)
When emitting a state update, restore `_self_mutable` to the value it had
previously so that `yield` in the middle of `async with self` does not result
in an immutable StateProxy.

Fix #3869
2024-09-05 14:36:33 -07:00
Vishnu Deva
593515784c
update overflowY in AUTO_HEIGHT_JS from hidden to scroll (#3882) 2024-09-05 10:23:00 -07:00
benedikt-bartscher
22ad950c5d
gitignore .web (#3885) 2024-09-05 10:22:22 -07:00
Elijah Ahianyo
2d6e531e49
Remove demo template (#3888) 2024-09-05 10:22:07 -07:00
Masen Furer
677ae314fb
Use correct flexgen backend URL (#3891) 2024-09-05 10:21:46 -07:00
Elijah Ahianyo
dade940632
[REF-3592]Promote rx.progress from radix themes (#3878)
* Promote `rx.progress` from radix themes

* fix pyi

* add warning when accessing `rx._x.progress`
2024-09-05 10:21:32 -07:00
Samarth Bhadane
d0b9b955b8
Update find_replace (#3886) 2024-09-04 16:11:33 -07:00
Samarth Bhadane
59047303c9
/health endpoint for K8 Liveness and Readiness probes (#3855)
* Added API Endpoint

* Added API Endpoint

* Added Unit Tests

* Added Unit Tests

* main

* Apply suggestions from Code Review

* Fix Ruff Formatting

* Update Socket Events

* Async Functions
2024-09-03 18:34:03 -07:00
Nikhil Rao
15a9f0a104
Disk state manager don't use byref (#3874) 2024-09-03 13:42:35 -07:00
Khaleel Al-Adhami
c07a983f05
add var_operation and move some operations to the new style (#3841)
* add var_operations and move some operations to the new style

* change bound style

* can't assume int anymore

* slice is not hashable (how did this work bef)

* convert to int explicitly

* move the rest of the operations to new style

* fix bool guess type

* forgot to precommit dangit

* add type ignore to bool for now
2024-09-03 11:39:05 -07:00
Khaleel Al-Adhami
f3426456ad
fix var in bare (#3873) 2024-09-03 11:33:54 -07:00
Nikhil Rao
853d72e4a5
Remove watchfiles and watchdog [REF-2133] [REF-3694] (#3862) 2024-09-02 09:38:17 -07:00
Tim Child
99a0236d21
Allow passing kwarg for toasts (#3857) 2024-08-30 23:55:01 -07:00
Khaleel Al-Adhami
629850162a
implement disk state manager (#3826)
* implement disk state manager

* put states inside of a folder

* return root state all the time

* factor out code

* add docs for token expiration

* cache states directory

* call absolute on web directory

* change dir to app path when testing the backend

* remove accidental 🥒

* test disk for now

* modify schema

* only serialize specific stuff

* fix issue in types

* what is a kilometer

* create folder if it doesn't exist in write

* this code hates me

* check if the file isn't empty

* add try except clause

* add check for directory again
2024-08-30 17:26:10 -07:00
Masen Furer
c457b43ab1
[REF-3416] [REF-3632] Update fastapi, gunicorn, watchdog deps (#3859) 2024-08-30 16:36:33 -07:00
Masen Furer
356deb5457
[REF-3589] raise EventHandlerArgMismatch when event handler args don't match spec (#3853)
* test_component: improve valid/invalid event trigger tests

Add test cases for event triggers defined as annotations.

Add additional cases around lambda returning different values.

Improve assertions for invalid tests (each line needs its own `pytest.raises`).

More invalid test cases.

* [REF-3589] raise EventHandlerArgMismatch when event handler args don't match spec

Improve error message for common issue.

Previously when the event handler arguments didn't match the spec, the
traceback resulted in:

```
OSError: could not get source code
```

Now this problem is traceable as a distinct error condition and users are
empowered to debug their code and reference the documentation (to be updated)
for further information.

* raise EventFnArgMismatch when lambda args don't match event trigger spec

Improve error message for another common issue encountered in the reflex framework.

Previous error message was

```
TypeError: index.<locals>.<lambda>() takes 0 positional arguments but 1 was given
```

* Fix up lambda test cases

* call_event_fn: adjust number of args for bound methods
2024-08-29 16:05:15 -07:00
Elijah Ahianyo
e6080a7707
[REF-3568][REF-3569]Remove deprecations (#3852)
* Remove deprecations

* remove prop conversion

* fix tests

* fix slight issue

* fix darglint
2024-08-29 15:46:18 -07:00
Elijah Ahianyo
4d9f427b19
[REF-3597] Type check Radio items (#3856) 2024-08-29 13:23:21 -07:00
benedikt-bartscher
dd6feff13f
Get attribute access type fix (#3803)
* add failing test

* catch unhandled NotImplementedError
2024-08-29 09:45:24 -07:00
Masen Furer
8f396fc348
ImmutableVar perf optimizations (#3814)
* Use lru_cache on expensive typing-related functions

* Skip instantiation of VarData unless data was actually merged

* Revert "integration: bump listening timeout to 1800 seconds"

This reverts commit a94eedff6d.

* Revert "integration: bump listening timeout to 1200 seconds"

This reverts commit 86563b66a4.
2024-08-28 10:02:16 -07:00
Masen Furer
3fa9f1fc06
[REF-3633] [main] Introduce a workaround for enterprise users who get stuck with httpx.get SSL (#3847)
* [REF-3633] Introduce a workaround for enterprise users who get stuck with httpx.get SSL

Setting SSL_NO_VERIFY=1 will disable SSL verification during `reflex init`

* Also install fnm using `reflex.utils.net.get`
2024-08-28 09:33:31 -07:00
Masen Furer
be71254250
Fix double-quoting of defaultColorMode (#3840)
If the user provided an `appearance` or `color_mode` value to `rx.theme`, then
the resulting value ended up being double-double-quoted in the resulting JS
output.

Instead remove the quotes from the context.js.jinja2 and always pass appearance
as a Var.
2024-08-26 17:17:39 -07:00
Masen Furer
1d9a154d5b
guess_type: if the type is optional, treat it like it's "not None" (#3839)
* guess_type: if the type is optional, treat it like it's "not None"

When guessing the type for an Optional annotation, the Optional was already
being stripped off, but this value was being ignored, except for error
messages. So actually use the Optional-stripped value.

* Strip Optional when casting Var .to
2024-08-26 16:26:17 -07:00
Khaleel Al-Adhami
ea15b184c0
fully migrate vars into new system (#3743)
* fully migrate vars into new system

* i hate rufffff (no i don't)

* fix silly pright issues (except colormode and state)

* remove all instances of Var.create

* create immutable callable var and get rid of more base vars

* implement hash for all functions

* get reflex-web to compile

* get it to compile reflex-web successfully

* fix tests

* fix pyi

* use override from typing_extension

* put plotly inside of a catch

* dicts are unusable sadly

* fix silly mistake

* overload equals to special case immutable var

* improve test_cond

* solve more CI issues, down to 94 failures

* down to 20 errors

* down to 13 errors

* pass all testcases

* fix pyright issues

* reorder things

* use get origin more

* use fixed_type logic

* various optimizations

* go back to passing test cases

* use less boilerplate

* remove unnecessary print message

* remove weird comment

* add test for html issue

* add type ignore

* fix another silly issue

* override get all var data for var operations call

* make integration tests pass

* fix immutable call var

* better logic for finding parent class

* use even better logic for finding state wrt computedvar

* only choose the ones that are defined in the same module

* small dict to large dict

* [REF-3591] Remove chakra-related files from immutable vars PR (#3821)

* Add comments to html metadata component (#3731)

* fix: add verification for path /404 (#3723)

Co-authored-by: coolstorm <manas.gupta@fampay.in>

* Use the new state name when setting `is_hydrated` to false (#3738)

* Use `._is_mutable()` to account for parent state proxy (#3739)

When a parent state proxy is set, also allow child StateProxy._self_mutable to
override the parent's `_is_mutable()`.

* bump to 0.5.9 (#3746)

* add message when installing requirements.txt is needed for chosen template during init (#3750)

* #3752 bugfix add domain for XAxis (#3764)

* fix appharness app_source typing (#3777)

* fix import clash between connectionToaster and hooks.useState (#3749)

* use different registry when in china, fixes #3700 (#3702)

* do not reload compilation if using local app in AppHarness (#3790)

* do not reload if using local app

* Update reflex/testing.py

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>

* Bump memory on relevant actions (#3781)

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>

* [REF-3334] Validate Toast Props (#3793)

* [REF-3536][REF-3537][REF-3541] Move chakra components into its repo(reflex-chakra) (#3798)

* fix get_uuid_string_var (#3795)

* minor State cleanup (#3768)

* Fix code wrap in markdown (#3755)

---------

Co-authored-by: Alek Petuskey <alek@pynecone.io>
Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com>
Co-authored-by: coolstorm <manas.gupta@fampay.in>
Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Khaleel Al-Adhami <khaleel.aladhami@gmail.com>
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>

* pyproject.toml: bump to 0.6.0a1

* pyproject.toml: depend on reflex-chakra>=0.6.0a

New Var system support in reflex-chakra 0.6.0a1

* poetry.lock: relock dependencies

* integration: bump listening timeout to 1200 seconds

* integration: bump listening timeout to 1800 seconds

* Use cached_var_no_lock to avoid ImmutableVar deadlocks (#3835)

* Use cached_var_no_lock to avoid ImmutableVar deadlocks

ImmutableVar subclasses will always return the same value for a _var_name or
_get_all_var_data so there is no need to use a per-class lock to protect a
cached attribute on an instance, and doing so actually is observed to cause
deadlocks when a particular _cached_var_name creates new LiteralVar instances
and attempts to serialize them.

* remove unused module global

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: Alek Petuskey <alek@pynecone.io>
Co-authored-by: Manas Gupta <53006261+Manas1820@users.noreply.github.com>
Co-authored-by: coolstorm <manas.gupta@fampay.in>
Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
Co-authored-by: Shubhankar Dimri <dimrishubhi@gmail.com>
Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>
2024-08-26 13:28:18 -07:00
elvis kahoro
a265fb4ae5
Add comments to DataList components (#3827)
* fix: Adding missing comments to the data list

* fix: Ran make pyi
2024-08-23 18:29:33 -07:00
Masen Furer
56c24f5432
Upper bound for reflex-chakra dependency (#3824)
* Upper bound for reflex-chakra dependency

We have to make a breaking change in reflex-chakra, and it will happen in 0.6.0, so ensure that reflex 0.5.10 never installs the breaking version of reflex-chakra.

* Relock deps
2024-08-23 12:59:34 -07:00
Elijah Ahianyo
9c656a0f9c
Fix benchmark tests (#3822) 2024-08-23 11:55:18 -07:00
Alek Petuskey
13a6d538a9
Fix code wrap in markdown (#3755) 2024-08-20 12:11:39 -07:00
benedikt-bartscher
2d9380a6fd
minor State cleanup (#3768) 2024-08-20 12:10:13 -07:00
Shubhankar Dimri
9c70971dc6
fix get_uuid_string_var (#3795) 2024-08-20 10:25:37 -07:00
Elijah Ahianyo
1f3779f40e
[REF-3536][REF-3537][REF-3541] Move chakra components into its repo(reflex-chakra) (#3798) 2024-08-19 13:41:31 -07:00
Elijah Ahianyo
4190a79835
[REF-3334] Validate Toast Props (#3793) 2024-08-15 09:30:32 -07:00
Alek Petuskey
b01c4b6c6a
Bump memory on relevant actions (#3781)
Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
2024-08-13 15:49:43 -07:00
Thomas Brandého
634c0916f6
do not reload compilation if using local app in AppHarness (#3790)
* do not reload if using local app

* Update reflex/testing.py

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-08-13 23:14:38 +02:00
Khaleel Al-Adhami
910bcdb017
use different registry when in china, fixes #3700 (#3702) 2024-08-12 03:06:34 -07:00
Thomas Brandého
0eff63eed4
fix import clash between connectionToaster and hooks.useState (#3749) 2024-08-12 03:04:55 -07:00
benedikt-bartscher
b58ce1082e
fix appharness app_source typing (#3777) 2024-08-11 17:42:39 -07:00
Shubhankar Dimri
911c2af044
#3752 bugfix add domain for XAxis (#3764) 2024-08-09 12:12:49 -07:00
Thomas Brandého
1a3a6f4a34
add message when installing requirements.txt is needed for chosen template during init (#3750) 2024-08-09 12:08:16 -07:00
Masen Furer
1131caebe8
bump to 0.5.9 (#3746) 2024-08-06 13:43:12 -07:00
Masen Furer
3309c0e533
Use ._is_mutable() to account for parent state proxy (#3739)
When a parent state proxy is set, also allow child StateProxy._self_mutable to
override the parent's `_is_mutable()`.
2024-08-05 14:03:49 -07:00
Masen Furer
7d9ed7e2ce
Use the new state name when setting is_hydrated to false (#3738) 2024-08-05 14:03:30 -07:00
Manas Gupta
c7e30522bc
fix: add verification for path /404 (#3723)
Co-authored-by: coolstorm <manas.gupta@fampay.in>
2024-08-05 14:02:47 -07:00
Alek Petuskey
76627c2076
Add comments to html metadata component (#3731) 2024-08-01 13:24:39 -07:00
Khaleel Al-Adhami
ad14f38329
add type hinting to existing types (#3729)
* add type hinting to existing types

* dang it darglint

* i cannot
2024-07-31 12:01:17 -07:00
benedikt-bartscher
129adc941a
add test for initial state dict (#3727) 2024-07-31 11:37:53 -07:00
benedikt-bartscher
2629366b23
fix initial_value for computed_var (#3726)
* fix initial_value for computed_var

* fix initial_value in pyi
2024-07-31 10:00:52 -07:00
Khaleel Al-Adhami
1c400043c6
[REF-3328] Implement __getitem__ for ArrayVar (#3705)
* half of the way there

* implement __getitem__ for array

* add some tests

* add fixes to pyright

* fix default factory

* implement array operations

* format code

* fix pyright issue

* give up

* add object operations

* add test for merge

* pyright 🥺

* use str isntead of _var_name

Co-authored-by: Masen Furer <m_github@0x26.net>

* wrong var_type

* make to much nicer

* add subclass checking

* enhance types

* use builtin list type

* improve typing even more

* i'm awaiting october

* use even better typing

* add hash, json, and guess type method

* fix pyright issues

* add a test and fix lots of errors

* fix pyright once again

* add type inference to list

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-07-30 15:38:32 -07:00
Masen Furer
06833f6d8d
[REF-3203] Find a DOM event-like object in addEvents (#3706) 2024-07-29 17:17:51 -07:00
Khaleel Al-Adhami
800685da68
fix silly bug when style is set directly to breakpoints (#3719)
* fix silly bug when style is set directly to breakpoints

* add helpful comment

Co-authored-by: Masen Furer <m_github@0x26.net>

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-07-29 16:57:33 -07:00
Masen Furer
4cdd87d851
Bump to v0.5.8 (#3716) 2024-07-29 09:52:45 -07:00
paoloemilioserra
2e726f1bb9
Update vars.py (#3659)
Prevent a validation error from pydantic/v1 that cannot find _var_name, etc. in __dataclass_fields__
2024-07-28 17:51:08 -07:00
Masen Furer
a4e3f05601
[REF-3375] useMemo on generateUUID props to maintain consistent value (#3708)
When using rx.vars.get_uuid_string_var, wrap the prop Var in `useMemo` so that
the value remains consistent across re-renders of the component.

Fix #3707
2024-07-26 17:10:08 -07:00
Thomas Brandého
c4346c2624
update init prompt to use new templates from reflex-dev/templates (#3677) 2024-07-25 10:51:44 -07:00
Thomas Brandého
d389f4b5ca
fix var warning (#3704) 2024-07-25 10:50:18 -07:00
Khaleel Al-Adhami
ede5cd1f2c
[REF-3321] implement var operation decorator (#3698)
* implement var operation decorator

* use older syntax

* use cast and older syntax

* use something even simpler

* add some tests

* use old union tactics

* that's not how you do things

* implement arithmetic operations while we're at it

* add test

* even more operations

* can't use __bool__

* thanos snap

* forgot ruff

* use default factory

* dang it darglint

* i know i should have done that but

* convert values into literalvars

* make test pass

* use older union tactics

* add test to string var

* pright why do you hate me 🥺
2024-07-25 09:34:14 -07:00
Masen Furer
0845d2ee76
[REF-3184] [REF-3339] Background task locking improvements (#3696)
* [REF-3184] Raise exception when encountering nested `async with self` blocks

Avoid deadlock when the background task already holds the mutation lock for a
given state.

* [REF-3339] get_state from background task links to StateProxy

When calling `get_state` from a background task, the resulting state instance
is wrapped in a StateProxy that is bound to the original StateProxy and shares
the same async context, lock, and mutability flag.

* If StateProxy has a _self_parent_state_proxy, retrieve the correct substate

* test_state fixup
2024-07-23 15:28:38 -07:00
Thomas Brandého
b9927b6f49
notifying frontend about backend error looks better (#3491) 2024-07-23 13:58:15 -07:00
Khaleel Al-Adhami
ea016314b0
[REF-3227] implement more literal vars (#3687)
* implement more literal vars

* fix super issue

* pyright has a bug i think

* oh we changed that

* fix docs

* literalize vars recursively

* do what masen told me :D

* use dynamic keys

* forgot .create

* adjust _var_value

* dang it darglint

* add test for serializing literal vars into js exprs

* fix silly mistake

* add  handling for var and none

* use create safe

* is none bruh

* implement function vars and do various modification

* fix None issue

* clear a lot of creates that did nothing

* add tests to function vars

* added simple fix smh

* use fconcat to make an even more complicated test
2024-07-22 12:45:23 -07:00
Elijah Ahianyo
9666244a87
[REF-3273] Add SVG circle, polygon and rect components (#3684) 2024-07-22 12:05:50 -07:00
Elijah Ahianyo
decdc857be
rx.list Dont set/hardcode list_style_position css prop (#3695) 2024-07-22 10:56:34 -07:00
Masen Furer
8b45d289bd
reflex init --ai fixups (#3691)
* reflex.build polling: catch exceptions and retry

Extend interval to 2 seconds to reduce server load.

* Add function to check if a string looks like a generation hash

* reflex init: allow --template to be a generation hash if --ai is specified
2024-07-19 14:05:53 -07:00
Thomas Brandého
921a5cd632
fix typo (#3689) 2024-07-19 18:02:50 +02:00
Masen Furer
1da606dd8e
[REF-3197] Browser init workflow (#3673) 2024-07-18 18:51:33 -07:00
Elijah Ahianyo
1bc1978c31
[REF-3135] Radix Primitive components should not ignore provided class_name prop (#3676) 2024-07-18 13:26:46 -07:00
Benyamin Zojaji
25aa0cbab1
add Persian translation and update the language links in the README.md files to include Persian (#3666) 2024-07-17 18:31:18 -07:00
Alek Petuskey
0a8b8a89b4
Benchmarking Updates (#3680)
* Benchmark test

* Lighthouse posthog

---------

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
2024-07-17 17:15:13 -07:00
Khaleel Al-Adhami
458cbfac59
[REF-3228] implement LiteralStringVar and format/retrieval mechanism (#3669)
* implement LiteralStringVar and format/retrieval mechanism

* use create safe

* add cached properties to ConcatVarOperation

* fix caches

* also include self

* fix inconsistencies in typings

* use default factory not default

* add missing docstring

* experiment with immutable var data

* solve pydantic issues

* add sorted function

* missing docs

* forgot ellipses

* give up on frozen

* dang it darglint

* fix string serialization bugs and remove unused code

* add returns statement

* whitespace moment

* add simple test for string concat

* export ConcatVarOperation
2024-07-17 17:01:27 -07:00
Masen Furer
94c4c2f29f
bump to 0.5.7 (#3678) 2024-07-16 11:38:56 -07:00
Alek Petuskey
93231f8168
Improve graphing asethetic (#3611)
* Improve graphing asthetic

* Few more updates

* More style updates

* Update reflex/components/recharts/polar.py

Co-authored-by: Masen Furer <m_github@0x26.net>

* Address pr comments

* fix precommit

* Fix types

* PYI

* PYI update

---------

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Masen Furer <m_github@0x26.net>
2024-07-15 11:25:08 -07:00
lumin
ec35e4f256
feat: Improve documentation in Japanese README.md file (#3650) 2024-07-14 13:16:10 -07:00
Khaleel Al-Adhami
5b927f18d0
[REF-3222] define new JS-type var classes (#3668)
* define new JS-type var classes

* add docstring

* get rid of dataclass definitions and export all new vars

* order imports in the correct way

* only hash once
2024-07-12 14:42:08 -07:00
Manas Gupta
b04a7dab84
Update Radial Bar Component (#3662)
* add: radial bar properties

* add: generate new pyi file

* style: fix linting

---------

Co-authored-by: coolstorm <manas.gupta@fampay.in>
2024-07-12 13:29:21 -07:00
Masen Furer
0ed895cde7
debounce: pass through key and special_props (#3655)
These fields on the base Component were not being carried onto the
DebounceInput component (to be passed to the child).

Discovered while testing #3653
2024-07-12 13:27:19 -07:00
benedikt-bartscher
9663377374
cleanup unused useReducer import (#3667) 2024-07-12 12:55:25 -07:00
Elijah Ahianyo
eed0edc12a
Allow DebounceInput as child of FormControl Component (#3660) 2024-07-11 16:07:25 -07:00
benedikt-bartscher
dc33d208b4
fix Var.contains pyi (#3663) 2024-07-11 16:06:32 -07:00
benedikt-bartscher
86a2f923f6
Pkg resources deprecation (#3646)
* fix typo

* migrate pkg_resources to importlib
2024-07-11 11:22:03 -07:00
benedikt-bartscher
3c0cb3fd6a
migrate deprecated connections to net_connections (#3641)
* migrate deprecated connections to net_connections

* check for psutil version
2024-07-11 11:21:34 -07:00
benedikt-bartscher
460afc2e10
fix unclosed file (#3639) 2024-07-11 11:20:54 -07:00
Khaleel Al-Adhami
d4d077818c
[REF-3225] implement __format__ for immutable vars (#3617)
* implement format for immutable vars

* add some basic test

* make reference only after formatting

* win over pyright

* hopefully now pyright doesn't hate me

* forgot some _var_data

* i don't know how imports work

* use f_string var and remove assignments from pyi file

* override post_init to not break immutability

* add create_safe and test for it
2024-07-11 11:19:38 -07:00
benedikt-bartscher
3039b54a75
add module prefix to generated state names (#3214)
* add module prefix to state names

* fix state names in test_app

* update state names in test_state

* fix state names in test_var

* fix state name in test_component

* fix state names in test_format

* fix state names in test_foreach

* fix state names in test_cond

* fix state names in test_datatable

* fix state names in test_colors

* fix state names in test_script

* fix state names in test_match

* fix state name in event1 fixture

* fix pyright and darglint

* fix state names in state_tree

* fix state names in redis only test

* fix state names in test_client_storage

* fix state name in js template

* add `get_state_name` and `get_full_state_name` helpers for `AppHarness`

* fix state names in test_dynamic_routes

* use new state name helpers in test_client_storage

* fix state names in test_event_actions

* fix state names in test_event_chain

* fix state names in test_upload

* fix state name in test_login_flow

* fix state names in test_input

* fix state names in test_form_submit

* ruff

* validate state module names

* wtf is going on here?

* remove comments leftover from refactoring

* adjust new test_add_style_embedded_vars

* fix state name in state.js

* fix integration/test_client_state.py

new SessionStorage feature was added with more full state names that need to be formatted in

* fix pre-commit issues in test_client_storage.py

* adjust test_computed_vars

* adjust safe-guards

* fix redis tests with new exception state

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-07-11 11:13:57 -07:00
Masen Furer
d378e4a70c
benchmarks.yml: use node 18.x with reflex-web@main (#3657) 2024-07-11 10:43:09 -07:00
Thomas Brandého
7ba61ced14
Make domain props work for y_axis (#3652) 2024-07-11 10:35:34 -07:00
Thomas Brandého
4f9a75b390
add warning when using css props on recharts (#3651) 2024-07-11 10:34:39 -07:00
Masen Furer
1cfc811506
[REF-3266] Check for pydantic v1 outside of try/except (#3643)
If pydantic v1 is already installed, there is no reason to restore the original
pydantic modules, which seems to introduce subtle incompatibilities with some
pydantic versions.

Perform the pydantic version check early on and exit for v1 before doing
anything with the sys.modules.

Fix #3642
2024-07-10 12:28:39 -07:00
Tom Gotsman
4c61838608
Tom/recharts missing props (#3645)
* fix axis orientation prop

* add margin prop explanation

* active bar and on animation start

* remove data key from y-axis

* precommit and pyi generator

---------

Co-authored-by: Tom Gotsman <tomgotsman@Toms-MacBook-Pro.local>
Co-authored-by: Tom Gotsman <tomgotsman@toms-mbp.lan>
2024-07-09 18:10:51 -07:00
Jishnu N
690b719437
[REF-3160] fix rx.Var._replace raise TypeError on invalid kwargs (#3625)
* fix: unexpected kwargs raise type error, on _replace

* add: docstring for _replace, test for invalid kwargs replace

* add: parametrize var for replace test

* fix: computed_var _replace with invalid kwargs
2024-07-09 11:19:29 -07:00
Maxim Vlah
fa71edd224
Fix the error boundary (#3637)
* - added possibility to pass front- and backend exception handlers to rx.App
- wrapped the app with ErrorBoundary component to catch rendering errors

* added missing exception handler to reflex.app._process

* regenerated pyi

* fix unit tests for exception handler validation

* fix typing error in ErrorBoudary

* - fix error_bounday pyi
- minor refactoring of error boundary
- removed error boundary from 404 page

* added missing inspect module import after merging main

* fix typing error

* Clean up ErrorBoundary component

* Remove custom _render function
* Remove special imports in Component base class
* Simplify hooks for better composability

* test_exception_handlers: also test in prod mode

* fixed color prop

* fixed error boundary bug and removed hardcoding of the frontend event exception state

* formatted the code after conflict resolution

* fixed type of the error_boundary

* ruff format

---------

Co-authored-by: Maxim Vlah <m.vlah@senbax.de>
Co-authored-by: Masen Furer <m_github@0x26.net>
2024-07-09 11:19:14 -07:00
abulvenz
5071245127
feat: Adding an event to go back just as the user would. (#3636)
* feat: Adding an event to go back just as the user would.

* fix: Simplification suggested by masenf.

* fix: And now apply the fix to the right function.
2024-07-09 11:18:02 -07:00
benedikt-bartscher
d621115f9b
add Bare SQLAlchemy mutation tracking, improve typing (#3628) 2024-07-09 11:13:28 -07:00
Masen Furer
9e1789a6c2
[REF-3076] Do not purge .web/pages in dev mode (#3592)
* [REF-3067] Do not purge .web/pages in dev mode

Avoid race condition in hot reload that occurs when pages are removed before
they are recreated.

Fix #3416

* use constants instead of hardcoded string
2024-07-08 20:17:38 -07:00
Maxim Vlah
772a3ef893
Catch unhandled errors on both frontend and backend (#3572) 2024-07-08 19:26:11 -07:00
benedikt-bartscher
6d3321284c
fix sqla python_type issues, add tests (#3613) 2024-07-08 19:21:08 -07:00
benedikt-bartscher
09ff952d01
only write .gitignore if needed (#3618) 2024-07-08 19:19:19 -07:00
Masen Furer
e71acececc
pyproject.toml: bump to 0.5.6 (#3635) 2024-07-08 17:31:36 -07:00
benedikt-bartscher
f71400896b
gitignore external assets by default (#3621) 2024-07-08 12:30:56 -07:00
Tom Gotsman
b20f3ac29a
update graphing (#3606)
* update graphing

* fix pyi

* update graphing

rebase#

* fix pyi

* precommit fail

* fix pyi generator file

* update pyi again

* pyi

* fix pyi generator to have single line builtin check

* change dict to Dict

---------

Co-authored-by: Tom Gotsman <tomgotsman@toms-mbp.lan>
Co-authored-by: Tom Gotsman <tomgotsman@Toms-MacBook-Pro.local>
Co-authored-by: Lendemor <thomas.brandeho@gmail.com>
2024-07-04 14:03:47 +02:00
Alek Petuskey
efe6954552
minor chart clean up (#3551)
* minor chart clean up

* PYI

* fix base pyi

* fix pyi issues

* fix cartesian.pyi

---------

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Lendemor <thomas.brandeho@gmail.com>
2024-07-04 03:27:07 +02:00
Khaleel Al-Adhami
046c0f9760
add immutable var class (#3607)
* add immutable var class

* add missing docs

* override _replace

* fix type imports

* override create as well

* remove deprecated properties and arguments

* remove unused code in ImmutableVar

* fix namespace issue

* no Self in 3.8
2024-07-03 11:23:04 -07:00
Tom Gotsman
59752d0cde
small update (#3612)
Co-authored-by: Tom Gotsman <tomgotsman@toms-mbp.lan>
2024-07-03 09:13:40 -07:00
benedikt-bartscher
8304886cac
dedupe config overrides (#3600) 2024-07-03 17:34:22 +02:00
Masen Furer
7cbd2848ce
[REF-3157] Avoid SQLModel metaclass conflict (#3610)
Ensure that reflex.utils.compat is loaded whenever `reflex` itself is imported
to try and avoid the sqlmodel metaclass conflict error that arises when
sqlmodel is imported first with pydantic v2, but reflex Model inherits from
rx.Base which is based on pydantic v1.

Fix #3515
2024-07-03 15:58:21 +02:00
Masen Furer
75c5fa2ffe
[REF-3220] Fix rx.cancel_upload EventSpec (#3608)
The formatting of the upload ID had extra single quotes that were not needed.
Now that `_var_name_unwrapped` is used, any `str`-like Vars will automatically
be formatted with backticks
2024-07-03 15:55:41 +02:00
Masen Furer
df7d7b0ba0
Update links to /docs/library/dynamic-rendering/foreach/ (#3609) 2024-07-02 13:41:26 -07:00
benedikt-bartscher
b742afb27f
do not get_config in global scope (#3597)
* do not get_config in global scope

* ruff fixes

* pydantic v1 compatibility
2024-07-01 10:17:40 -07:00
Thomas Brandého
f0bab665ce
split lifespan and middleware logic in separate mixin files (#3557)
* split lifespan and middleware logic in separate mixin files

* fix for 3.8

* fix for unit tests

* add missing sys import

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-06-29 08:50:04 -07:00
benedikt-bartscher
ad1d82f7ad
cleanup unused check (#3590) 2024-06-29 08:48:31 -07:00
Masen Furer
f1dafc0373
pyi_generator cleanup: ruff, remove fully qualified reflex. names (#3591)
* pyi_generator: avoid fully qualified names for reflex. types

The previous method added quite a large line diff to the pyi files, so for now,
lets just add the `Breakpoints` import to the default set along with Var,
EventHandler, Style and others.

* pyi_generator: fix generated files using ruff

also generate updated pyi files in reflex/experimental namespace

* remove black from dev dependencies

* poetry.lock: relock deps

* Update all pyi files with new formatting

* pre-commit fixes

* pyi_generator: fix __init__.pyi files again
2024-06-29 08:48:01 -07:00
Alek Petuskey
1c3d65dd52
Change Strategy Prop to Literal (#3575)
* Better type strategy prop

* Add beter description

* Pre commit

* fix pyi generation

* Default prop assignment must be Var to pass type checking

* fix script.pyi

---------

Co-authored-by: Alek Petuskey <alekpetuskey@Aleks-MacBook-Pro.local>
Co-authored-by: Masen Furer <m_github@0x26.net>
2024-06-28 18:02:37 -07:00
Khaleel Al-Adhami
d253fc4dcd
add responsive props to radix components (#3583)
* implement basic behavior to handle both radix and css

* add all components in theme, AND change pyi to include path of reflex types

* order type annotations in pyi_generator (#3585)

* order type annotations in pyi_generator

* run pyi_generator

* classvars should not be backend vars (#3578)

* classvars should not be backend vars

* cleanup RESERVED_BACKEND_VAR_NAMES

* order type annotations in pyi_generator (#3585)

* order type annotations in pyi_generator

* run pyi_generator

* do not validate non-cached var deps (#3576)

* do not validate non-cached var deps

* further improve Exceptions for misconfigured var deps

* order type annotations in pyi_generator (#3585)

* order type annotations in pyi_generator

* run pyi_generator

* fix git merge remains

* define function globally

* use more modern annotations

* only trigger when direct value and not state

* simplify unions

* accidentally removed avatar oop

---------

Co-authored-by: benedikt-bartscher <31854409+benedikt-bartscher@users.noreply.github.com>
2024-06-28 17:01:23 -07:00
benedikt-bartscher
b7651e214b
add computed backend vars (#3573)
* add computed backend vars

* finish computed backend vars, add tests

* fix token for AppHarness with redis state manager

* fix timing issues

* add unit tests for computed backend vars

* automagically mark cvs with _ prefix as backend var

* fully migrate backend computed vars

* rename is_backend_variable to is_backend_base_variable

* add integration test for implicit backend cv, adjust comments

* replace expensive backend var check at runtime

* keep stuff together

* simplify backend var check method, consistent naming, improve test typing

* fix: do not convert properties to cvs

* add test for property

* fix cached_properties with _ prefix in state cls
2024-06-28 17:01:07 -07:00
benedikt-bartscher
bcc7a61452
improve backend var determination (#3587)
* cleanup reserved backend var check

* cleanup backend var determination mess

* add tests for hidden and class methods
2024-06-28 14:07:39 -07:00
Elijah Ahianyo
8f2cbb5ea1
[REF-2588]Clear color mode local storage for dev mode (#3548)
* Clear color mode local storage

* use the last compiled time logic to determine when to clear local storage

* precommit fix

* app harness fix

* run prettier on reflex/.templates/web/utils/helpers/color_mode.js

* make sure last_compiled_time is updated for stateless apps as well.

* set the chkara-ui-color-mode cookie instead of clearing it, so it is integrated in the app's useEffect cycle

* fix CI

* fix import formatting

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-06-28 13:57:34 -07:00
benedikt-bartscher
a6bdaf1bbe
fix var dependency over properties (#3588) 2024-06-28 12:48:28 -07:00
benedikt-bartscher
33d7ec1f04
copy backend vars from mixins (#3580)
* copy backend vars from mixins

* fix and improve backend var mixin test
2024-06-28 10:42:41 -07:00
benedikt-bartscher
a7e4594fdc
Deprecate cached var (#3582)
* deprecate cached_var partial

* migrate cached_var to var(cache=True)

* fix darglint (typo)
2024-06-28 10:14:55 -07:00
Masen Furer
1ca0a27d4d
[REF-3164] Hack to fix Windows hot reload + Uvicorn upgrade (#3584)
Now that we have a hack to work around hot reload issues in Uvicorn on Windows,
we can remove the pin and use the latest version.
2024-06-28 10:07:27 -07:00
benedikt-bartscher
44d27f9e4c
do not validate non-cached var deps (#3576)
* do not validate non-cached var deps

* further improve Exceptions for misconfigured var deps
2024-06-27 17:00:55 -07:00
benedikt-bartscher
8e66c9b3c7
classvars should not be backend vars (#3578)
* classvars should not be backend vars

* cleanup RESERVED_BACKEND_VAR_NAMES
2024-06-27 16:03:36 -07:00
benedikt-bartscher
2027a2f09f
order type annotations in pyi_generator (#3585)
* order type annotations in pyi_generator

* run pyi_generator
2024-06-27 15:58:11 -07:00
Masen Furer
8eb834f816
Add a link to backend in connection error (#3044)
* Automatic authentication for backend on Github Codespaces

When running reflex on Github codespaces, the port forwarding mechanism
requires authentication, which happens automatically when first accessing the
port via HTTPS; however since the backend connects over the WSS protocol
instead, it gets an access error with no way to redirect to Github's
authentication servers to get the port open.

This PR adds an automatic redirection mechanism to a backend route when there
is a connection error accessing the frontend. After the backend route loads, it
redirects back to the frontend, but now it can connect to the backend via
websocket because the port forward is authenticated.

* manually update .pyi file 🫨
2024-06-27 12:20:03 -07:00
Khaleel Al-Adhami
82a0d7f3fb
introduce customizable breakpoints (#3568)
* introduce customizable breakpoints
2024-06-27 01:34:49 +03:00
Thomas Brandého
6863e8ce8c
show the value causing problem in deprecation warning (#3558) 2024-06-26 13:25:23 -07:00
Thomas Brandého
cca037421b
add props for tabs (#3560) 2024-06-26 13:24:47 -07:00
Elijah Ahianyo
31bd75ff39
[REF-3185][REF-3180]Dont escape backticks in JS string interpolation (#3566)
* Dont escape backticks in JS string interpolation

* add unit tests

* Fix darglint

* add a note to re-visit after new Var API is implemented

* tests should have a good meaning
2024-06-26 13:23:07 -07:00
benedikt-bartscher
d425ede401
fix formatting (#3574) 2024-06-26 13:19:55 -07:00
Thomas Brandého
3c8179d987
add compilation time in log (#3563) 2024-06-26 09:58:35 -07:00
Thomas Brandého
237aa22306
update dependency pinning (#3556) 2024-06-26 09:53:12 -07:00
Elijah Ahianyo
28a72efc83
Radio group fix deprecation warning for creating vars with strings (#3567) 2024-06-26 09:52:56 -07:00
abulvenz
d90fa8a266
fix: Using default components instead of chakra. (#3570) 2024-06-26 09:23:53 -07:00
Thomas Brandého
764f723829
fix small typing issue (#3562) 2024-06-26 09:23:20 -07:00
Masen Furer
956bc0a397
Add Clipboard component for handling global on_paste event (#3513)
* Add Clipboard component for handling global on_paste event

* py3.8 compat

* py3.8 compat (p2)
2024-06-26 09:22:24 -07:00
benedikt-bartscher
9d71bcbbb5
bare sqlalchemy session + tests (#3522)
* add bare sqlalchemy session, Closes #3512

* expose sqla_session at module level, add tests, improve typing

* fix table name

* add model_registry fixture, improve typing

* did not meant to push this

* add docstring to model_registry

* do not expose sqla_session in reflex namespace
2024-06-25 15:29:01 +02:00
Emmanuel Onwuegbusi
e4c17deafb
Fix radix radio cards component (#3545)
* ruff format

* fix radio card component

* generated radio_cards.pyi

* ruff format
2024-06-25 15:23:30 +02:00
Masen Furer
0314d19e7e
Ensure rx.match gets memoized to avoid excessive re-rendering (#3552) 2024-06-25 15:20:04 +02:00
Masen Furer
6947ec3a28
bump to 0.5.5 (#3550) 2024-06-24 18:36:20 -07:00
benedikt-bartscher
41efe12e9a
Validate ComputedVar dependencies, add tests (#3527) 2024-06-24 16:11:42 -07:00
Elijah Ahianyo
f037df0977
[REF-3056] Config knob for redis StateManager expiration times (#3523) 2024-06-24 16:03:30 -07:00
alex
44233c9cd1
Added german translation and updated the language links in the README.md files to include german. (#3547)
Co-authored-by: alex <alex@alexdot.me>
2024-06-24 16:35:35 +02:00
Masen Furer
b2b0da036d
[REF-3149] Bring back py3.12 hot reload warning (#3537)
Warning for issue #3536

Co-authored-by: Lendemor <thomas.brandeho@gmail.com>
2024-06-24 16:24:42 +02:00
Thomas Brandého
046dbdef63
fix hydration error (#3542) 2024-06-21 21:34:47 +02:00
Masen Furer
1a74ff4d45
[REF-3079] state.js: disconnect websocket for window "pagehide" event (#3540)
All major browser use a "bfcache" to freeze pages when navigating away from the
domain, then they restore the page when going back.

However if the page uses websockets, these get kind of stuck unless you
disconnect them before freezing (and have a mechanism for reconnecting, which
we already do).

Ref: https://web.dev/articles/bfcache

Fix #3478
2024-06-21 18:28:29 +02:00
HongyuHansonYao
f41e852b0d
Hanson/radial bar chart (#3532)
* refactored event triggers

* update eventhandler method

* updated pyi files

* .

* Update pyi

* new pyis

* lower passing bar for test coverage to 60

---------

Co-authored-by: Hongyu Yao <hongyuyao@hongyus-mbp-3.lan>
Co-authored-by: Nikhil Rao <nikhil@reflex.dev>
Co-authored-by: Hongyu Yao <hongyuyao@Hongyus-MacBook-Pro-3.local>
2024-06-20 21:41:10 -07:00
Masen Furer
c2c6286537
Always treat the call_script callback as a string of JS code (#3521) 2024-06-20 18:05:25 -07:00
Masen Furer
958c4fa7f2
Abstract color_mode related Var creation (#3533)
* StatefulComponent event handler useCallback dependency array

Ensure the useCallback dependency array for event handlers also handled
destructuring objects and the `...` rest parameter.

Avoid hooks that are not variable declarations.

* Abstract color_mode related Var creation

* Allow `set_color_mode` to take a parameter at compile time
* Update type hinting of `Var._replace` to indicate that it returns BaseVar

* color_mode_button with allow_system=True uses new set_color_mode API

`set_color_mode` is now a CallableVar and uses very similar logic internally,
so this bit of code can be replaced.

* Fix for pydantic v1.10.17
2024-06-20 16:46:48 -07:00
HongyuHansonYao
4318bb597f
Hanson/tooltip-improvement/props (#3525)
* added props for tooltip

* formatted

* added pyi

* new pyi

---------

Co-authored-by: Hongyu Yao <hongyuyao@Hongyus-MacBook-Pro-3.local>
2024-06-20 15:09:33 -07:00
Tom Gotsman
a4a5d52e21
add in rx.el.style (#3511) 2024-06-20 11:59:08 -07:00
Thomas Brandého
6709b49cfa
pass validation of valid_parent if inheriting from valid class (#3519) 2024-06-19 23:00:18 +02:00
Thomas Brandého
6ad679ad66
fix segmented_control (#3516)
* fix segmented_control

* fix 3.8 imports

* fix 3.8 typing

* add valid_parent for SegmentedControlItem
2024-06-19 17:47:49 +02:00
Masen Furer
ffb24ceeee
Improve ClientState compatibility with rx.input (#3490)
* Ignore type checking for generic aliases in _var_name_unwrapped

* Allow ClientStateVar.set_value to be used with text inputs

* client_state: If var_name is not provided, create a random name

* client_state: partition the arg value to get `_e0` from `_e0.target.value`
2024-06-19 07:01:46 -07:00
Thomas Brandého
0d39237b3c
upgrade to latest ruff (#3497)
* upgrade to latest ruff

* try to fix dep review

* try to fix dep review (2)

* upgrade black

* upgrade black (2)

* update allowed dependencies

* update allowed dependencies (2)

* update allowed dependencies (3)

* wait between interim and final in yield test

* remove previous commit, increase delay between yield

* forgot to save on the time.sleep(1) removal

* fix integration (maybe?)

* fix pyi?

* what even is going on

* what is realityi?

* test another fix for app harness

* try to wait even longer?

* force uvloop to be optional

* downpin fastapi < 0.111, remove changes to test
2024-06-19 12:32:13 +02:00
Thomas Brandého
d6d14b3f72
add allow_system prop to colormode iconbutton, and clean up logic (#3507)
* add allow_system prop to colormode iconbutton, and clean up logic

* remove segmentedcontrol change from this PR

* make it work for chakraColorProvider too

* add comment to explain resolved_color_mode
2024-06-19 02:02:27 +02:00
Masen Furer
af3c9be97c
Protect StateProxy with an asyncio.Lock (#3508)
* test_background_task: dispatch multiple async tasks

Use asyncio.gather to dispatch multiple tasks from a single background task
that all compete over the `async with self` lock. Even though the state itself
has a lock, each StateProxy instance should only allow a single `async with
self` context to run at a time.

* Protect StateProxy with an asyncio.Lock

Allow multiple tasks to reference the same StateProxy without stomping on each
other when entering an `async with self` context to acquire the state lock and
ultimately modify the state.
2024-06-18 09:48:12 -07:00
HongyuHansonYao
eb397dacc4
(WIP) recharts fixes batch #3 (#3496)
* remove stroke and fill from label as they are unsupported by recharts

* refacted legend

* added props to reference line

* updated type for stroke_width, added stroke, updated type for x y

* added x y to reference dot

* updated reference area

* regenerated pyi

* new pyis

* regenerated pyi

---------

Co-authored-by: Hongyu Yao <hongyuyao@Hongyus-MacBook-Pro-3.local>
Co-authored-by: Hongyu Yao <hongyuyao@hongyus-mbp-3.lan>
2024-06-17 17:07:24 -07:00
Kelechi Ebiri
2b2cdf9847
Feat: Add Session storage to store data on client storage (#3420) 2024-06-17 17:31:36 -04:00
Emmanuel Onwuegbusi
b78fa6f210
fix checkbox_group component (#3454) 2024-06-17 17:02:20 -04:00
Thomas Brandého
ed05f57fc9
Make .web configurable with REFLEX_WEB_WORKDIR (#3462) 2024-06-17 16:17:00 -04:00
Sagar Hedaoo
6fdc5a84db
Updated radio group component (#3474) 2024-06-17 16:10:03 -04:00
Thomas Brandého
44d2bd4970
fix missing event triggers from docs (#3495)
* fix missing event triggers from docs

* fix nit

* go for simpler fix
2024-06-14 22:03:35 +02:00
Elijah Ahianyo
69e4bbc301
[REF-2830] server side events and stateless components should not require not require a backend (#3475)
* `rx.color_mode.icon`, `rx.color_mode.button` and `rx.color_mode.switch` should not require a backend`

* remove print statement

* unit tests and precommit fix

* add unit tests

* change logic to check if event handlers actually contain state. Also delay websocket object check in state.js so server side events can get executed for stateless apps

* make sure events are not queued for server side events particularly ones that call queueEvents(clear_local_storage, clear_cookies, remove_local_storage, remove_cookies) when the app is stateless(no ws)

* fix unit tests

* fix broken unit tests in test_app

* modify socket check in processEvent to only return if socket exists and theres any event in the queue that requires state

* Apply suggestions from code review

make queueEvent call async

Co-authored-by: Masen Furer <m_github@0x26.net>

* await queueEventIfSocketExists

* Revert "await queueEventIfSocketExists"

This reverts commit 9ef8070b87.

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-06-14 09:48:53 -07:00
Thomas Brandého
bdc0defa4a
update launch message (#3453)
* update launch message

* update for nit

* address changes
2024-06-13 11:03:42 -07:00
Masen Furer
b15cee4f10
pyproject.toml: bump to 0.5.4 (#3480) 2024-06-13 10:23:57 -07:00
Thomas Brandého
1c8bebcaf6
allow return from run_in_thread (#3477) 2024-06-13 09:59:05 -07:00
Thomas Brandého
42f34f763e
add event triggers for rx.video (#2700) 2024-06-13 08:03:44 -07:00
HongyuHansonYao
5d3eef7031
Hanson recharts batch #2 (#3472)
1. Updated recharts version to the newest - recharts.py
2. Added `legend_type` back for cartesian class, it was currently commented out - cartesian.py
3. Added `vertical_points` and `horizontal_points` to CartesianGrid class - cartesian.py
4. Added `ticks` `tick` `tick_count` `tick_line` `tick_size` `min_tick_gap`props to Axis class - cartesian.py
5. Refactored `on_click` `on_mouse_down` `on_mouse_up` `on_mouse_move` `on_mouse_out` `on_mouse_enter` `on_mouse_leave` event triggers of `Axis` class using Masen's new method - cartesian.py
6. Added `on_animation_begin` and `on_animation_end` event trigger to `Bar(Cartesian)` class - cartesian.py
7. Added `id` `is_animation_active` `animation_begin` `animation_duration` `animation_easing` `unit` `min_point_size` `name`  prop to `Bar(Cartesian)` class - cartesian.py.
8. Added `unit` `name` props to `Area(Cartesian)` class - cartesian.py
9. Added `unit` `name` props to `Line(Cartesian)` class - cartesian.py
10. Added `id` `is_animation_active` `animation_begin` `animation_duration` `animation_easing` props to `Scatter(Recharts)` class - cartesian.py
11. Refactored eventtriggers for `Scatter(Recharts)` class using Masen's new method - cartesian.py
12. Change the var type of stack_id in `Area(Cartesian)` class to be string and int, it used to be only a string. - cartesian.py
13. Added `name_key` prop and `on_animation_start` and `on_animation_end` prop to `Funnul(Recharts)` class cartesian.py
14. Added `on_mouse_down` `on_mouse_up` `on_mouse_over` `on_mouse_out` event triggers to `PieChart(ChartBase)` and also refactored using Masen's new method - Charts.py
15. Refaactored event triggers for referenceDot(Reference) class using Masen's new method. - Cartesian.py
16. Refactored event triggers for ChartBase(RechartsCharts) class using Masen's new method. - Cartesian.py
17. Refactored event triggers for Piechart(ChartBase) class using Masen's new method, Added `on_mouse_down` `on_mouse_up` `on_mouse_over` `on_mouse_out` event triggers - Cartesian.py

Co-authored-by: Hongyu Yao <hongyuyao@hongyus-mbp-3.lan>
2024-06-12 11:40:05 -07:00
Thomas Brandého
463f7829d4
swap all use of get_event_triggers to rx.EventHandler props (#3458) 2024-06-12 11:11:29 -07:00
Thomas Brandého
462b023019
use add_imports everywhere (#3448) 2024-06-12 09:26:45 -07:00
Carlos
991f6e0183
[REF-3012] Add defs, lineargradient and stop html elements (#3467) 2024-06-12 09:21:36 -07:00
Elijah Ahianyo
8c8156f3aa
[REF-3016] Allow special characters in upload ID (#3449) 2024-06-12 09:21:21 -07:00
Masen Furer
c3c06a1fcb
compat: do not patch pydantic if the installed version starts with "1." (#3482)
In pydantic 1.10.16 (hopefully the last version), they added the `pydantic.v1`
namespace to make transitioning to the v2 package easier without changing code.

However, Reflex was depending on pydantic v1 NOT having `pydantic.v1` to skip
patching names from `v1` into the top level `pydantic` (normally we do this to
force sqlmodel to use v1, even when the v2 package is installed).

Unbreak CI
2024-06-11 19:16:35 -07:00
Masen Furer
bd799a2680
Override _var_is_string when handling str literals (#3473)
* Override _var_is_string when handling str literals

Maintain the pre 0.5.4 behavior when dealing with string literal
props, without displaying the deprecation warning.

Wait, isn't it weird to pass `_var_is_string=False` when the type is actually a str??

Yes, yes it is. However this is currently needed to avoid raising the
DeprecationWarning internally. These str-type vars with
_var_is_string set to false are handled by
`reflex.utils.format.format_prop`, but setting them to be
_var_is_string=True causes them to get quoted twice, which is not
what we want.

Var operations refactor will take care of cleaning this up, but for
now, we will go with the hack.

* Ignore type checks

Since I'm using an `isinstance` check now, the type checker thinks that `value`
could possibly be a string (instead of Any), which raises typing errors that
have to be ignored (they were ignored before implicitly due to being Any-typed)
2024-06-11 13:18:34 -07:00
Masen Furer
66f0a49b75
Pass _var_is_string parameter to Var.create (#3470) 2024-06-10 14:32:32 -07:00
Tom Gotsman
ccf617ba85
small update to fix radial bar chart (#3468)
* small update to fix radial bar chart

* update add data prop to radar

---------

Co-authored-by: Tom Gotsman <tomgotsman@toms-mbp.lan>
2024-06-10 14:03:47 -07:00
Tom Gotsman
cc0f0bcc22
Fix recharts errors part 1 (#3450) 2024-06-07 17:30:09 -07:00
Alexander Morgan
ad3134413b
Make better/less use of dict.keys() calls (#3455) 2024-06-07 14:28:44 -07:00
Masen Furer
bb44d51f2f
[REF-2879] Make client_state work without global refs (local only) (#3379)
* Make client_state work without global refs (local only)

* client_state: if the default is str, mark _var_is_string=True

Ensure that a string default is not rendered literally

* add `to_int` as a Var operation

* Allow an event handler lambda to return a Var in some cases

If an lambda is passed to an event trigger and it returns a single Var, then
treat it like the Var was directly passed for the event trigger.

This allows ClientState.set_var to be used within a lambda.
2024-06-07 13:29:52 -07:00
Masen Furer
e138d9dfd0
state.js: set event_processing = false when websocket connects (#3443)
* test_connection_banner: Improve assertions

* Actually assert on the presence or absense of the connection banner
* Update XPATH selector to find the connection toast
* Add event handling while backend down to verify queue functionality
* Bring backend down while an event is running to ensure queue does not get
  blocked (#3404)

* state.js: set event_processing = false when websocket connects

In case an event was pending when the websocket went down, allow further events
to be processed when it comes back up.

Fix #3404

* test_connection_banner: wait for token indicating backend is connected

* test_connection_banner: increase delay time

make the time window longer in which the backend can go down and get stuck in
event_processing=true for better test reliability

* Ensure the redis connection is reset in new backend thread

Redis has an event loop affinity and needs to be attached to the event loop
that the thread is running.

* Reset event_processing on disconnect

* if the socket never comes back up, it still allows client-side events to be
  processed
* on_mount events may start running before the socket is up, so resetting the
  flag on connect may break event determinism (test_event_chain.py)
2024-06-07 13:29:25 -07:00
Thomas Brandého
c04ed58d2e
default color_mode is now system color (#3457) 2024-06-07 09:56:07 -07:00
benedikt-bartscher
e42d4ed9ef
[REF-3009] type transforming serializers (#3227)
* wip type transforming serializers

* old python sucks

* typing fixups

* Expose the `to` parameter on `rx.serializer` for type conversion

Serializers can also return a tuple of `(serialized_value, type)`, if both ways
are specified, then the returned value MUST match the `to` parameter.

When initializing a new rx.Var, if `_var_is_string` is not specified and the serializer returns a `str` type, then mark `_var_is_string=True` to indicate that the Var should be treated like a string literal.

Include datetime, color, types, and paths as "serializing to str" type.

Avoid other changes at this point to reduce fallout from this change:

  Notably, the `serialize_str` function does NOT cast to `str`, which
  would cause existing code to treat all Var initialized with a str as a
  str literal even though this was NOT the default before.

Update test cases to accomodate these changes.

* Raise deprecation warning for rx.Var.create with string literal

In the future, we will treat strings as string literals in the JS code. To get
a Var that is not treated like a string, pass _var_is_string=False.

This will allow our serializers to automatically identify cast string literals
with less special cases (and the special cases need to be explicitly
identified).

* Add test case for mismatched serialized types

* fix old python

* Remove serializer returning a tuple feature

Simplify the logic; instead of making a wrapper function that returns
a tuple, just save the type conversions in a separate global.

* Reset the LRU cache when adding new serializers

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-06-07 09:50:10 -07:00
Elliot Kroo
168501d58a
Address an issue with pydantic v2 models as Vars (#3396)
* Addresses an issue with pydantic v2 models as Vars

It looks like there's an issue with state vars
which are pydantic v2 models...  Here's a
reproducible test case:

```python
import reflex as rx
from pydantic import BaseModel
from reflex.utils.serializers import serializer

class User(BaseModel):
    has_image: bool = False

@serializer
def serialize_user(user: User) -> dict:
    return user.dict()

class State(rx.State):
    user: User = None

def index() -> rx.Component:
    return rx.container(
        rx.cond(State.user,
                rx.text(State.user.has_image),
                rx.text("No user"))
    )

app = rx.App()
app.add_page(index)
```

This app works only with pydantic <2 installed:

```bash
reflex-test $ reflex run
...
AttributeError: 'FieldInfo' object has no attribute 'outer_type_'
reflex-test $ pip install pydantic==1.10.15
─────────────────────────────────── Starting Reflex App ───────────────────────────────────
Compiling: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 13/13 0:00:00
─────────────────────────────────────── App Running ───────────────────────────────────────
App running at: http://localhost:3000
```

Looks like this is caused by `outer_type_` no
[longer existing][1] in pydantic v2.  I'm guessing
this was introduced back in [v0.4.6][2].

1: https://github.com/pydantic/pydantic/discussions/7217
2: 86526cba51

This change explicitly ignores pydantic v2 models in
`get_attribute_access_type`, rather than trying to treat
them as v1 models.

* ruff formatting

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-06-07 09:47:54 -07:00
HongyuHansonYao
4e990d2716
Recharts supporting radix color, add event triggers (#3430)
Co-authored-by: Hongyu Yao <hongyuyao@hongyus-mbp-3.lan>
2024-06-07 09:47:12 -07:00
Masen Furer
6e719d4c83
[REF-2977] [REF-2982] Merge layout prop and automatic darkmode (#3442)
* [REF-2977] [REF-2982] Merge layout prop and automatic darkmode

* Expose `template` prop in rx.plotly
* Set default `template` to a color_mode_cond that responds to dark mode
* Merge user-provided `layout` and `template` props into the serialized
  plot data

* pyi_generator: avoid affecting the HTML Template component

* Raise warning when importing rx.plotly without plotly installed

* Remove PlotlyLib component and consolidate imports [fixup]
2024-06-07 09:42:50 -07:00
Masen Furer
fb173908db
Only run pyi_generator on files in reflex/components or reflex/__init__.py (#3452) 2024-06-06 21:31:17 -07:00
Devon Stewart
39d9a9f8eb
[bug] Avoid deleting endpoint port when running on Replit (#3447)
* "if codespace_name" repeated, no-op

* Special-case replit.dev

* Codifying a ruff future
2024-06-06 14:00:00 -07:00
benedikt-bartscher
f672391618
Webdriver ArgOptions improvements (#3429)
* allow to pass custom selenium ArgOptions to webdriver

* allow to pass capabilities to auto generated driver options
2024-06-06 13:59:41 -07:00
Thomas Brandého
3579513964
fix warning about props (#3451) 2024-06-06 13:45:22 -07:00
Thomas Brandého
e1244b4ea6
promote toast to main namespace (#3422) 2024-06-06 10:38:35 -07:00
Thomas Brandého
4b955d3831
clean up hooks and update component to use add_hooks (#3439) 2024-06-06 10:26:04 -07:00
Elijah Ahianyo
44ad9a7311
[REF-2956] Fail When Backend port or frontend port is explicitly provided and the port is in use (#3432) 2024-06-05 11:46:00 -07:00
Milo Chen
bbd320b3ce
fix: correct zh_tw and zh_cn README for hyperlink issues (#3440)
* fix: correct zh_tw and zh_cn README for hyperlink issues

* Update docs/zh/zh_cn/README.md

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

* Update docs/zh/zh_tw/README.md

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

---------

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
2024-06-05 19:11:20 +02:00
Masen Furer
765f349f02
[REF-3004] Use relative path to stylesheet for postcss-import compat (#3435)
* test_tailwind: include custom stylesheet

* [REF-3004] Use relative path to stylesheet for postcss-import compat

postcss-import balls all of the CSS up into a single file, which happens at
compile time. So, replace the `@/` with `../public` so the import paths can be
resolved relative to the `styles` directory.

* test_compiler: fix compile_stylesheets expectations

* Use constants.Dirs.PUBLIC instead of "public"
2024-06-05 10:02:05 -07:00
Masen Furer
447fe56833
bump version to 0.5.3 (#3446) 2024-06-05 10:01:17 -07:00
Masen Furer
096ecf3113
[REF-3006] Inline code rendered in rx.markdown has extra trailing space (#3426)
Avoid replacing newlines with whitespaces... these show up in the rendered
output 😱

Fix #3425
2024-06-05 16:55:02 +02:00
Elijah Ahianyo
6420fb1252
[REF-3010] Circular Imports Fix (#3433) 2024-06-04 11:50:02 -07:00
Elijah Ahianyo
a3cbfefb22
[REF-2602] Do not suppress import errors in rxconfig (#3434) 2024-06-04 11:48:52 -07:00
HongyuHansonYao
1c29bff998
Set use resize handler default to true (#3424)
* init

* empty commit

* set true

* set true

* set true

---------

Co-authored-by: Hongyu Yao <hongyuyao@hongyus-mbp-3.lan>
2024-06-03 12:42:22 -07:00
Milo Chen
6c1af838cf
PR zh/zh_tw readme update for relex 0.5.2 (#3415) 2024-06-03 10:29:58 -07:00
Carlos
7a12fe2c5e
include resize and radius props to the text area component (#3383)
* include resize and radius props to the text area component

* run scripts/make_pyi.py for text_area

* pre-commit fixup

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-05-31 17:45:59 -07:00
Masen Furer
b04e3a6ce9
[REF-1356] Track changes applied to Base subclass via helper method. (#2242) 2024-05-31 14:58:58 -07:00
Masen Furer
5995b32f5f
[REF-2978] Ignore Redis config_set for AWS ElastiCache (#3401) 2024-05-31 14:58:25 -07:00
Masen Furer
16fc3936a4
[REF-2202] Implement event handlers for Plotly (#3397)
* pyi_generator: do not generate kwargs for event trigger props

event triggers are handled separately

* Implement event handlers for Plotly

* py38 compat: from __future__ import annotations
2024-05-31 13:04:19 -07:00
HongyuHansonYao
d9e718d7bd
Layout property not pushed through on rx.plotly (#3394)
* init fix

* Update reflex/components/plotly/plotly.py

Co-authored-by: Masen Furer <m_github@0x26.net>

* plotly: treat `data` as a `dict`-type Var in _render

this allows the data to be passed directly as a figure or from a state var

* removed width height prop as they are no longer needed

* updated

* reverted some of the changes

* fixed unit tests

* regen pyi

---------

Co-authored-by: Hongyu Yao <hongyuyao@hongyus-mbp-3.lan>
Co-authored-by: Masen Furer <m_github@0x26.net>
Co-authored-by: Hongyu Yao <hongyuyao@Hongyus-MacBook-Pro-3.local>
2024-05-31 11:48:43 -07:00
Elijah Ahianyo
34bf25071a
[REF-2821]Improve Dynamic Imports (#3345)
* Improve import times

* add lazy loading to rx.el

* add lazy loading to reflex core components

* minor refactor

* Get imports working with reflex web

* get imports to work with all reflex examples

* refactor to define imports only in the root.

* lint

* deadcode remove

* update poetry deps

* unit tests fix

* app_harness fix

* app_harness fix

* pyi file generate

* pyi file generate

* sort pyi order

* fix pyi

* fix docker ci

* rework pyi-generator

* generate pyi for __init__ files

* test pyright

* test pyright ci

* partial pyright fix

* more pyright fix

* pyright fix

* fix pyi_generator

* add rx.serializer and others

* add future annotation import which fixes container CI, then also load recharts lazily

* add new pyi files

* pyright fix

* minor fixes for reflex-web and flexdown

* forward references for py38

* ruff fix

* pyi fix

* unit tests fix

* reduce coverage to 68%

* reduce coverage to 67%

* reduce coverage to 66%as a workaround to coverage's rounding issue

* reduce coverage to 66%as a workaround to coverage's rounding issue

* exclude lazy_loader dependency review checks.

* its lazy-loader

* Add docstrings and regenerate pyi files

* add link

* address Pr comments

* CI fix

* partially address PR comments.

* edit docstrings and fix integration tests

* fix typo in docstring

* pyi fix
2024-05-31 16:43:10 +00:00
Jishnu N
83d99889ec
refactor: radix section default size (#3406) 2024-05-30 20:52:01 -07:00
Masen Furer
2f1a68c975
pyproject.toml: bump to 0.5.2 (#3408) 2024-05-30 16:58:23 -07:00
Elijah Ahianyo
1a833d6b25
Recommend Running with REFLEX_USE_NPM=1 if npm run fails after installing packages with bun. (#3399) 2024-05-30 15:57:15 -07:00
Tom Gotsman
5652310840
update image for readme (#3395)
* update image for readme

* update based on Nikhil's comment

---------

Co-authored-by: Tom Gotsman <tomgotsman@toms-mbp.lan>
2024-05-30 12:23:56 -07:00
Kelechi Ebiri
d99c40a763
Add domain prop for the PolarRadiusAxis component (#3349) 2024-05-30 09:14:50 -07:00
Sagar Hedaoo
7f054fda9d
Updated in/readme.md with current readme (#3333) 2024-05-30 09:14:02 -07:00
Thomas Brandého
c7064b9a24
add config knob for react_strict_mode. default to True. also cleanup unused code (#3389) 2024-05-29 11:49:04 -07:00
Elijah Ahianyo
4b939caa7f
[REF-2895]Benchmarks getting skipped on merge (#3369) 2024-05-29 09:28:41 -07:00
benedikt-bartscher
93de407007
Explicit deps and interval for computed vars (#3231) 2024-05-28 12:27:27 -07:00
Masen Furer
ac1c660bf0
Radix Themes + Tailwind Harmony (#3355) 2024-05-28 12:21:28 -07:00
Thomas Brandého
33f71c6eef
add mapping between client_token and socket id (#3388) 2024-05-28 10:53:26 -07:00
abulvenz
6c6eaaa55f
External assets (#3220) 2024-05-28 09:39:25 -07:00
abulvenz
7c2056e960
feat: Optionally comparing fields in Var.contains, e.g. on rx.Base based types. (#3375)
* feat: Optionally comparing fields, e.g. on rx.Base based types.

* feat: Minimally invasive change.
Leave the current implementation as is. Added test.

* fix: Supporting old-school python versions.

* fix: Adding masenf's suggestions to use var instead of string.
2024-05-24 17:16:26 -07:00
Masen Furer
51d3b2cb21
url quote the str data passed to rx.download (#3381) 2024-05-24 09:44:09 -07:00
Masen Furer
653f00b046
[REF-2878] Map fontFamily to fontFamily and --default-font-family (#3380)
When setting the font_family prop for a component, also set the radix token
`--default-font-family` so that child radix components will inherit the font.
2024-05-23 15:54:39 -07:00
benedikt-bartscher
d96f051486
set config.deploy_url during AppHarness tests (#3359) 2024-05-23 09:23:07 -07:00
Masen Furer
ed39c27bfb
[REF-2915] ComponentState subclasses are always treated as mixin (#3372)
Always treat ComponentState subclasses as mixin, and explicitly pass
`mixin=False` in `.create` classmethod when intentionally creating a substate.

This allows a "base" ComponentState to have subclasses that also work as
ComponentState themselves.

Fix #3368
2024-05-22 16:12:33 -07:00
Thomas Brandého
956a526b20
add support for lifespan tasks (#3312)
* add support for lifespan tasks

* allow passing args to lifespan task

* add message to the cancel call

* allow asynccontextmanager as lifespan tasks

* Fix integration.utils.SessionStorage

Previously the SessionStorage util was just looking in localStorage, but the
tests didn't catch it because they were asserting the token was not None,
rather than asserting it was truthy.

Fixed here, because I'm using this structure in the new lifespan test.

* If the lifespan task or context takes "app" parameter, pass the FastAPI instance.

* test_lifespan: end to end test for register_lifespan_task

* In py3.8, Task.cancel takes no args

* test_lifespan: use polling to make the test more robust

Fix CI failure

* Do not allow task_args for better composability

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-05-22 12:07:03 -07:00
benedikt-bartscher
0b613d5d3b
do not check attribute type for var internals (#3357) 2024-05-22 11:35:42 -07:00
Angelina Sheyko
0c0dde127f
Added config for number of gunicorn workers (#3351) 2024-05-22 11:31:15 -07:00
owlur
6976fe6145
Update Korean README.md and synchronize code with the latest version (#3337) 2024-05-21 19:37:21 -07:00
Masen Furer
3e5bf00ba2
Bump to 0.5.1 (#3364) 2024-05-21 17:17:48 -07:00
Thomas Brandého
4bda3eb233
add style for orientation=vertical in tabs (#3332) 2024-05-21 16:21:46 -07:00
Santiago Botero
d40d992670
Update Spanish README.md (#3330) 2024-05-21 14:51:50 -07:00
seewind
f961e2daa0
#3321: Update Chinese README.md (#3350) 2024-05-21 14:50:36 -07:00
Eric Brown
d50be7eab1
Use twine environment variables if set (#3353) 2024-05-21 14:43:49 -07:00
Nikhil Rao
ff985aee22
Suppress runtime warnings (#3354) 2024-05-21 12:34:25 -07:00
Nikhil Rao
ec72448b8b
Catch more errors in frontend/backend (#3346) 2024-05-20 16:55:41 -07:00
benedikt-bartscher
656914edef
fix rx.cond with ComputedVars and use union type (#3336) 2024-05-19 12:14:46 -07:00
Eric Brown
b614e38047
Add some minimal validation of pyproject.toml (#3339) 2024-05-19 12:13:24 -07:00
Thomas Brandého
590d86ebf4
update README to use 0.5.0 (#3313) 2024-05-17 16:29:38 -07:00
Thomas Brandého
9ba179410b
wip connection toaster (#3242)
* wip connection toaster

* never duplicate toast for websocket-error

* wip update banner

* clean up PR

* fix for 3.8

* update pyi

* ConnectionToaster tweaks

* Use `has_too_many_connection_errors` to avoid showing the banner immediately
* Increase toast duration to avoid frequent, distracting flashing of the toast
* Automatically dismiss the toast when the connection comes back up
* Include `close_button` for user to dismiss the toast
* If the user dismisses the toast, do not show it again until the connection comes back and drops again
* Use `connection_error` var instead of a custom util_hook to get the message

* ConnectionPulser: hide behind toast

* Hide the connection pulser behind the toast (33x33)
* Add a title (tooltip) that shows the connection error

* Re-add connection pulser to default overlay_component

If the user dismisses the toast, we still want to indicate that the backend is
actually down.

* Fix pre-commit issue from main

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-05-16 22:08:32 -07:00
Santiago Botero
99d59104ad
Add end line in .gitignore (#3309) 2024-05-16 13:22:44 -07:00
Masen Furer
bc6f0f70cb
Support replacing route on redirect (#3072)
* Support replacing route on redirect

Support next/router `.replace` interface to change page without creating a
history entry.

* test_event: include test cases for new "replace" kwarg
2024-05-16 13:21:40 -07:00
Masen Furer
89352ac10e
rx._x.client_state: react useState Var integration for frontend and backend (#3269)
New experimental feature to create client-side react state vars, save them in
the global `refs` object and access them in frontend rendering/event triggers
as well on the backend via call_script.
2024-05-16 13:20:26 -07:00
Thomas Brandého
47043ae787
throw error for componentstate in foreach (#3243) 2024-05-15 17:59:23 -07:00
benedikt-bartscher
48c504666e
properly replace ComputedVars (#3254)
* properly replace ComputedVars

* provide dummy override decorator for older python versions

* adjust pyi

* fix darglint

* cleanup var_data for computed vars inherited from mixin

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-05-15 15:01:14 -07:00
Masen Furer
c5f32db756
[REF-2787] add_hooks supports Var-wrapped hooks (#3248)
* [REF-2787] add_hooks supports Var-wrapped hooks

* Fix VarData definition in .pyi file to allow removal of type ignore comments
* Var.create and Var.create_safe accept _var_data parameter
* Replace instances where a set of imports was being passed to VarData
* Update code throughout reduce use of `._replace` to add VarData

* Fixup: user hooks _var_data.imports will never be iterable, just a single ImportDict
2024-05-15 14:59:45 -07:00
benedikt-bartscher
d96baac7d9
typed mixins and ComponentState (#3196)
* typed mixins

* implicit mixin=True kwarg for ComponentState subclasses

* fix: always init other subclasses

* adjust tests: all mixins support base vars now
2024-05-15 12:07:41 -07:00
benedikt-bartscher
87a3ddea7f
allow passing kwargs and options to selenium webdriver (#2894)
* allow passing kwargs to selenium webdriver

* always create driver options, add x11 class to chromium

* add driver_option_args
2024-05-15 11:58:10 -07:00
Eric Brown
30c8a07ba8
Adds dependency review action to verify allowed licensed dependencies (#3306)
This change will add a new action to scan the dependency's licenses
for any that may not be allowed for this project.

The pip-licenses command was run to get a dump of all the licenses
associated with this repo and put into the allow-licenses list.
Normally, you might only want to use deny-licenses list, but for
packages like Redis, there is no defined SPDX identifier for it.

Note: this list will require future maintenance as dependencies get
added that are not already in the allow list.

https://spdx.org/licenses/
https://github.com/raimon49/pip-licenses

Related to issue #2901

Signed-off-by: Eric Brown <eric_wade_brown@yahoo.com>
2024-05-15 11:55:18 -07:00
Yummy-Yums
efa9fcd6d5
FIX - Error: img is a self-closing tag and must neither have children nor use dangerouslySetInnerHTML. (#3307)
* fixed errors

* fix CI errors

* CI fix again

* used ruff formatting

* pyi fix

* fix app harness

---------

Co-authored-by: Elijah <elijahahianyo@gmail.com>
2024-05-15 11:52:50 -07:00
Elijah Ahianyo
ccc40e0c8d
Bump Bun version (#3281) 2024-05-15 11:57:11 +02:00
Eric Brown
bd3df68bef
Mirgrate from pip to uv (#3285)
In order to improve build time performance, this change switches
usage of pip to uv. The uv command is a pip alternative promising
much faster installs of Python packages.

For more information on uv, see:
https://github.com/astral-sh/uv

Closes: #2748

Signed-off-by: Eric Brown <eric_wade_brown@yahoo.com>
2024-05-15 11:56:16 +02:00
Masen Furer
76c8b2dfbd
Get action, cancel, on_dismiss and on_auto_close working for rx.toast (#3216)
* Get `action` and `cancel` working for rx.toast

Respect defaults set in ToastProvider toast_options when firing a toast with
it's own ToastProps set.

* Update reflex/components/sonner/toast.py

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>

* Move queueEvent formatting into rx.utils.format module

Implement on_auto_close and on_dismiss callbacks inside ToastProps

* Update rx.call_script to use new format.format_queue_events

Replace duplicate logic in rx.call_script for handling the callback function.

* Move PropsBase to reflex.components.props

This base class will be exposed via rx._x.PropsBase and can be shared by other
wrapped components that need to pass a JS object full of extra props.

---------

Co-authored-by: Thomas Brandého <thomas.brandeho@gmail.com>
2024-05-15 11:54:52 +02:00
Elijah Ahianyo
89a83ecd42
[REF-2803] Add imports benchmarks (#3272) 2024-05-14 23:19:46 -07:00
Elijah Ahianyo
ea5a3d44e7
[REF-2814]Throw Warning for Projects Created in OneDrive on Windows (#3304)
* Throw Warning for Projects Created in OneDrive on Windows

* precommit

* remove dead code

* REFLEX_USE_NPM escape hatch to opt out of bun

In some unsupported environments, we need to just not use bun. Further
investigation needed.

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
2024-05-14 18:47:08 -07:00
757 changed files with 106603 additions and 75235 deletions

1
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1 @@
@reflex-dev/reflex-team

View File

@ -2,7 +2,6 @@
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---

View File

@ -0,0 +1,19 @@
---
name: Enhancement Request
about: Suggest an enhancement for an existing Reflex feature.
title: ''
labels: 'enhancement'
assignees: ''
---
**Describe the Enhancement you want**
A clear and concise description of what the improvement does.
- Which feature do you want to improve? (and what problem does it have)
- What is the benefit of the enhancement?
- Show an example/usecase were the improvement are needed.
**Additional context**
Add any other context here.

View File

@ -0,0 +1,18 @@
---
name: Feature Request
about: Suggest a new feature for Reflex
title: ''
labels: 'feature request'
assignees: ''
---
**Describe the Features**
A clear and concise description of what the features does.
- What is the purpose of the feature?
- Show an example / use cases for the new feature.
**Additional context**
Add any other context here.

View File

@ -6,7 +6,7 @@
#
# Exit conditions:
# - Python of version `python-version` is ready to be invoked as `python`.
# - Poetry of version `poetry-version` is ready ot be invoked as `poetry`.
# - Poetry of version `poetry-version` is ready to be invoked as `poetry`.
# - If `run-poetry-install` is true, deps as defined in `pyproject.toml` will have been installed into the venv at `create-venv-at-path`.
name: 'Setup Reflex build environment'
@ -18,7 +18,7 @@ inputs:
poetry-version:
description: 'Poetry version to install'
required: false
default: '1.3.1'
default: '1.8.3'
run-poetry-install:
description: 'Whether to run poetry install on current dir'
required: false
@ -106,3 +106,8 @@ runs:
run: |
source ${{ inputs.create-venv-at-path }}/*/activate
poetry install --only-root --no-interaction
- name: Install uv
shell: bash
run: |
poetry run pip install uv

2
.github/codeql-config.yml vendored Normal file
View File

@ -0,0 +1,2 @@
paths-ignore:
- "**/tests/**"

View File

@ -5,7 +5,7 @@ on:
types:
- closed
paths-ignore:
- '**/*.md'
- "**/*.md"
permissions:
contents: read
@ -15,22 +15,21 @@ defaults:
shell: bash
env:
PYTHONIOENCODING: 'utf8'
PYTHONIOENCODING: "utf8"
TELEMETRY_ENABLED: false
NODE_OPTIONS: '--max_old_space_size=4096'
DATABASE_URL: ${{ secrets.DATABASE_URL }}
NODE_OPTIONS: "--max_old_space_size=8192"
PR_TITLE: ${{ github.event.pull_request.title }}
jobs:
reflex-web:
if: github.event.pull_request.merged == true
# if: github.event.pull_request.merged == true
strategy:
fail-fast: false
matrix:
# Show OS combos first in GUI
os: [ubuntu-latest]
python-version: ['3.11.4']
node-version: ['16.x']
python-version: ["3.12.8"]
node-version: ["18.x"]
runs-on: ${{ matrix.os }}
steps:
@ -49,12 +48,12 @@ jobs:
uses: actions/checkout@v4
with:
repository: reflex-dev/reflex-web
ref: reflex-ci
ref: main
path: reflex-web
- name: Install Requirements for reflex-web
working-directory: ./reflex-web
run: poetry run pip install -r requirements.txt
run: poetry run uv pip install -r requirements.txt
- name: Init Website for reflex-web
working-directory: ./reflex-web
run: poetry run reflex init
@ -62,79 +61,16 @@ jobs:
run: |
# Check that npm is home
npm -v
poetry run bash scripts/benchmarks/benchmarks.sh ./reflex-web prod
poetry run bash benchmarks/lighthouse.sh ./reflex-web prod
env:
LHCI_GITHUB_APP_TOKEN: $
- name: Run Benchmarks
# Only run if the database creds are available in this context.
if: ${{ env.DATABASE_URL }}
run: poetry run python scripts/benchmarks/lighthouse_score_upload.py "$GITHUB_SHA" ./integration/benchmarks/.lighthouseci
run: poetry run python benchmarks/benchmark_lighthouse.py "$GITHUB_SHA" ./integration/benchmarks/.lighthouseci
env:
GITHUB_SHA: ${{ github.sha }}
simple-apps-benchmarks:
if: github.event.pull_request.merged == true
env:
OUTPUT_FILE: benchmarks.json
timeout-minutes: 50
strategy:
# Prioritize getting more information out of the workflow (even if something fails)
fail-fast: false
matrix:
# Show OS combos first in GUI
os: [ubuntu-latest, windows-latest, macos-12]
python-version: ['3.8.18', '3.9.18', '3.10.13', '3.11.5', '3.12.0']
exclude:
- os: windows-latest
python-version: '3.10.13'
- os: windows-latest
python-version: '3.9.18'
- os: windows-latest
python-version: '3.8.18'
# keep only one python version for MacOS
- os: macos-latest
python-version: '3.8.18'
- os: macos-latest
python-version: '3.9.18'
- os: macos-latest
python-version: '3.10.13'
- os: macos-12
python-version: '3.12.0'
include:
- os: windows-latest
python-version: '3.10.11'
- os: windows-latest
python-version: '3.9.13'
- os: windows-latest
python-version: '3.8.10'
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: ${{ matrix.python-version }}
run-poetry-install: true
create-venv-at-path: .venv
- name: Install additional dependencies for DB access
run: poetry run pip install psycopg2-binary
- name: Run benchmark tests
env:
APP_HARNESS_HEADLESS: 1
PYTHONUNBUFFERED: 1
run: |
poetry run pytest -v benchmarks/ --benchmark-json=${{ env.OUTPUT_FILE }} -s
- name: Upload benchmark results
# Only run if the database creds are available in this context.
if: ${{ env.DATABASE_URL }}
run:
poetry run python scripts/benchmarks/simple_app_benchmark_upload.py --os "${{ matrix.os }}"
--python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
--benchmark-json "${{ env.OUTPUT_FILE }}"
--db-url "${{ env.DATABASE_URL }}" --branch-name "${{ github.head_ref || github.ref_name }}"
--event-type "${{ github.event_name }}" --actor "${{ github.actor }}" --pr-id "${{ github.event.pull_request.id }}"
reflex-build-size:
reflex-dist-size: # This job is used to calculate the size of the Reflex distribution (wheel file)
if: github.event.pull_request.merged == true
timeout-minutes: 30
strategy:
@ -145,24 +81,21 @@ jobs:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: 3.11.5
python-version: 3.12.8
run-poetry-install: true
create-venv-at-path: .venv
- name: Install additional dependencies for DB access
run: poetry run pip install psycopg2-binary
- name: Build reflex
run: |
poetry build
- name: Upload benchmark results
# Only run if the database creds are available in this context.
if: ${{ env.DATABASE_URL }}
run:
poetry run python scripts/benchmarks/benchmark_reflex_size.py --os ubuntu-latest
--python-version 3.11.5 --commit-sha "${{ github.sha }}" --pr-id "${{ github.event.pull_request.id }}"
--db-url "${{ env.DATABASE_URL }}" --branch-name "${{ github.head_ref || github.ref_name }}"
--measurement-type "reflex-build" --path ./dist
poetry run python benchmarks/benchmark_package_size.py --os ubuntu-latest
--python-version 3.12.8 --commit-sha "${{ github.sha }}" --pr-id "${{ github.event.pull_request.id }}"
--branch-name "${{ github.head_ref || github.ref_name }}"
--path ./dist
reflex-plus-dependency-size:
reflex-venv-size: # This job calculates the total size of Reflex and its dependencies
if: github.event.pull_request.merged == true
timeout-minutes: 30
strategy:
@ -170,13 +103,17 @@ jobs:
fail-fast: false
matrix:
# Show OS combos first in GUI
os: [ubuntu-latest, windows-latest, macos-12]
python-version: ['3.11.5']
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.12.8"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Set up python
id: setup-python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
with:
@ -192,14 +129,15 @@ jobs:
source .venv/*/activate
poetry install --without dev --no-interaction --no-root
- name: Install additional dependencies for DB access
run: poetry run pip install psycopg2-binary
- name: Install uv
shell: bash
run: |
poetry run pip install uv
- if: ${{ env.DATABASE_URL }}
name: calculate and upload size
- name: calculate and upload size
run:
poetry run python scripts/benchmarks/benchmark_reflex_size.py --os "${{ matrix.os }}"
poetry run python benchmarks/benchmark_package_size.py --os "${{ matrix.os }}"
--python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
--pr-id "${{ github.event.pull_request.id }}" --db-url "${{ env.DATABASE_URL }}"
--pr-id "${{ github.event.pull_request.id }}"
--branch-name "${{ github.head_ref || github.ref_name }}"
--measurement-type "reflex-package" --path ./.venv
--path ./.venv

View File

@ -6,16 +6,16 @@ concurrency:
on:
push:
branches: ['main']
branches: ["main"]
# We don't just trigger on make_pyi.py and the components dir, because
# there are other things that can change the generator output
# e.g. black version, reflex.Component, reflex.Var.
paths-ignore:
- '**/*.md'
- "**/*.md"
pull_request:
branches: ['main']
branches: ["main"]
paths-ignore:
- '**/*.md'
- "**/*.md"
jobs:
check-generated-pyi-components:
@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: '3.11.5'
python-version: "3.12.8"
run-poetry-install: true
create-venv-at-path: .venv
- run: |

40
.github/workflows/check_node_latest.yml vendored Normal file
View File

@ -0,0 +1,40 @@
name: integration-node-latest
on:
push:
branches:
- main
pull_request:
branches:
- main
env:
TELEMETRY_ENABLED: false
REFLEX_USE_SYSTEM_NODE: true
jobs:
check_latest_node:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: ["3.12.8"]
split_index: [1, 2]
node-version: ["node"]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: ${{ matrix.python-version }}
run-poetry-install: true
create-venv-at-path: .venv
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: |
poetry run uv pip install pyvirtualdisplay pillow pytest-split
poetry run playwright install --with-deps
- run: |
poetry run pytest tests/test_node_version.py
poetry run pytest tests/integration --splits 2 --group ${{matrix.split_index}}

View File

@ -0,0 +1,86 @@
name: check-outdated-dependencies
on:
push: # This will trigger the action when a pull request is opened or updated.
branches:
- "release/**" # This will trigger the action when any branch starting with "release/" is created.
workflow_dispatch: # Allow manual triggering if needed.
jobs:
backend:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- uses: ./.github/actions/setup_build_env
with:
python-version: '3.10'
run-poetry-install: true
create-venv-at-path: .venv
- name: Check outdated backend dependencies
run: |
outdated=$(poetry show -oT)
echo "Outdated:"
echo "$outdated"
filtered_outdated=$(echo "$outdated" | grep -vE 'pyright|ruff' || true)
if [ ! -z "$filtered_outdated" ]; then
echo "Outdated dependencies found:"
echo "$filtered_outdated"
exit 1
else
echo "All dependencies are up to date. (pyright and ruff are ignored)"
fi
frontend:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: "3.10.16"
run-poetry-install: true
create-venv-at-path: .venv
- name: Clone Reflex Website Repo
uses: actions/checkout@v4
with:
repository: reflex-dev/reflex-web
ref: main
path: reflex-web
- name: Install Requirements for reflex-web
working-directory: ./reflex-web
run: poetry run uv pip install $(grep -ivE "reflex " requirements.txt)
- name: Install additional dependencies for DB access
run: poetry run uv pip install psycopg
- name: Init Website for reflex-web
working-directory: ./reflex-web
run: poetry run reflex init
- name: Run Website and Check for errors
run: |
poetry run bash scripts/integration.sh ./reflex-web dev
- name: Check outdated frontend dependencies
working-directory: ./reflex-web/.web
run: |
raw_outdated=$(/home/runner/.local/share/reflex/bun/bin/bun outdated)
outdated=$(echo "$raw_outdated" | grep -vE '\|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\|' || true)
echo "Outdated:"
echo "$outdated"
# Ignore 3rd party dependencies that are not updated.
filtered_outdated=$(echo "$outdated" | grep -vE 'Package|@chakra-ui|lucide-react|@splinetool/runtime|ag-grid-react|framer-motion|react-markdown|remark-math|remark-gfm|rehype-katex|rehype-raw|remark-unwrap-images|ag-grid' || true)
no_extra=$(echo "$filtered_outdated" | grep -vE '\|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-' || true)
if [ ! -z "$no_extra" ]; then
echo "Outdated dependencies found:"
echo "$filtered_outdated"
exit 1
else
echo "All dependencies are up to date. (3rd party packages are ignored)"
fi

103
.github/workflows/codeql.yml vendored Normal file
View File

@ -0,0 +1,103 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
schedule:
- cron: "36 7 * * 4"
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: javascript-typescript
build-mode: none
- language: python
build-mode: none
- language: actions
build-mode: none
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
config-file: .github/codeql-config.yml
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

17
.github/workflows/dependency-review.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: 'Dependency Review'
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v4
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
with:
allow-licenses: Apache-2.0, BSD-2-Clause, BSD-3-Clause, HPND, ISC, MIT, MPL-2.0, Unlicense, Python-2.0, Python-2.0.1, Apache-2.0 AND MIT, BSD-2-Clause AND BSD-3-Clause, Apache-2.0 AND BSD-3-Clause
allow-dependencies-licenses: 'pkg:pypi/lazy-loader'

View File

@ -6,13 +6,13 @@ concurrency:
on:
push:
branches: ['main']
branches: ["main"]
paths-ignore:
- '**/*.md'
- "**/*.md"
pull_request:
branches: ['main']
branches: ["main"]
paths-ignore:
- '**/*.md'
- "**/*.md"
permissions:
contents: read
@ -22,9 +22,11 @@ jobs:
timeout-minutes: 30
strategy:
matrix:
state_manager: ['redis', 'memory']
python-version: ['3.8.18', '3.11.5', '3.12.0']
runs-on: ubuntu-latest
state_manager: ["redis", "memory"]
python-version: ["3.11.11", "3.12.8", "3.13.1"]
split_index: [1, 2]
fail-fast: false
runs-on: ubuntu-22.04
services:
# Label used to access the service container
redis:
@ -45,16 +47,10 @@ jobs:
python-version: ${{ matrix.python-version }}
run-poetry-install: true
create-venv-at-path: .venv
- run: poetry run pip install pyvirtualdisplay pillow
- run: poetry run uv pip install pyvirtualdisplay pillow pytest-split pytest-retry
- name: Run app harness tests
env:
SCREENSHOT_DIR: /tmp/screenshots
REDIS_URL: ${{ matrix.state_manager == 'redis' && 'redis://localhost:6379' || '' }}
run: |
poetry run pytest integration
- uses: actions/upload-artifact@v4
name: Upload failed test screenshots
if: always()
with:
name: failed_test_screenshots
path: /tmp/screenshots
poetry run playwright install chromium
poetry run pytest tests/integration --retries 3 --maxfail=5 --splits 2 --group ${{matrix.split_index}}

View File

@ -2,13 +2,13 @@ name: integration-tests
on:
push:
branches: ['main']
branches: ["main"]
paths-ignore:
- '**/*.md'
- "**/*.md"
pull_request:
branches: ['main']
branches: ["main"]
paths-ignore:
- '**/*.md'
- "**/*.md"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.id }}
@ -27,36 +27,33 @@ env:
# TODO: can we fix windows encoding natively within reflex? Bug above can hit real users too (less common, but possible)
# - Catch encoding errors when printing logs
# - Best effort print lines that contain illegal chars (map to some default char, etc.)
PYTHONIOENCODING: 'utf8'
PYTHONIOENCODING: "utf8"
TELEMETRY_ENABLED: false
NODE_OPTIONS: '--max_old_space_size=4096'
DATABASE_URL: ${{ secrets.DATABASE_URL }}
NODE_OPTIONS: "--max_old_space_size=8192"
PR_TITLE: ${{ github.event.pull_request.title }}
jobs:
example-counter:
example-counter-and-nba-proxy:
env:
OUTPUT_FILE: import_benchmark.json
timeout-minutes: 30
strategy:
# Prioritize getting more information out of the workflow (even if something fails)
fail-fast: false
matrix:
# Show OS combos first in GUI
os: [ubuntu-latest, windows-latest, macos-12]
python-version: ['3.8.18', '3.9.18', '3.10.13', '3.11.5', '3.12.0']
os: [ubuntu-latest, windows-latest]
python-version: ['3.10.16', '3.11.11', '3.12.8', '3.13.1']
exclude:
- os: windows-latest
python-version: '3.10.13'
python-version: "3.11.11"
- os: windows-latest
python-version: '3.9.18'
- os: windows-latest
python-version: '3.8.18'
python-version: '3.10.16'
include:
- os: windows-latest
python-version: "3.11.9"
- os: windows-latest
python-version: '3.10.11'
- os: windows-latest
python-version: '3.9.13'
- os: windows-latest
python-version: '3.8.10'
runs-on: ${{ matrix.os }}
steps:
@ -74,9 +71,9 @@ jobs:
- name: Install requirements for counter example
working-directory: ./reflex-examples/counter
run: |
poetry run pip install -r requirements.txt
poetry run uv pip install -r requirements.txt
- name: Install additional dependencies for DB access
run: poetry run pip install psycopg2-binary
run: poetry run uv pip install psycopg
- name: Check export --backend-only before init for counter example
working-directory: ./reflex-examples/counter
run: |
@ -97,25 +94,37 @@ jobs:
# Check that npm is home
npm -v
poetry run bash scripts/integration.sh ./reflex-examples/counter dev
- name: Measure and upload .web size
if: ${{ env.DATABASE_URL }}
run:
poetry run python scripts/benchmarks/benchmark_reflex_size.py --os "${{ matrix.os }}"
--python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
--pr-id "${{ github.event.pull_request.id }}" --db-url "${{ env.DATABASE_URL }}"
--branch-name "${{ github.head_ref || github.ref_name }}"
--measurement-type "counter-app-dot-web" --path ./reflex-examples/counter/.web
- name: Install requirements for nba proxy example
working-directory: ./reflex-examples/nba-proxy
run: |
poetry run uv pip install -r requirements.txt
- name: Install additional dependencies for DB access
run: poetry run uv pip install psycopg
- name: Check export --backend-only before init for nba-proxy example
working-directory: ./reflex-examples/nba-proxy
run: |
poetry run reflex export --backend-only
- name: Init Website for nba-proxy example
working-directory: ./reflex-examples/nba-proxy
run: |
poetry run reflex init --loglevel debug
- name: Run Website and Check for errors
run: |
# Check that npm is home
npm -v
poetry run bash scripts/integration.sh ./reflex-examples/nba-proxy dev
reflex-web:
strategy:
fail-fast: false
matrix:
# Show OS combos first in GUI
os: [ubuntu-latest, windows-latest, macos-12]
python-version: ['3.10.11', '3.11.4']
os: [ubuntu-latest]
python-version: ["3.11.11", "3.12.8"]
env:
REFLEX_WEB_WINDOWS_OVERRIDE: '1'
REFLEX_WEB_WINDOWS_OVERRIDE: "1"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@ -134,9 +143,72 @@ jobs:
- name: Install Requirements for reflex-web
working-directory: ./reflex-web
run: poetry run pip install -r requirements.txt
run: poetry run uv pip install $(grep -ivE "reflex " requirements.txt)
- name: Install additional dependencies for DB access
run: poetry run pip install psycopg2-binary
run: poetry run uv pip install psycopg
- name: Init Website for reflex-web
working-directory: ./reflex-web
run: poetry run reflex init
- name: Run Website and Check for errors
run: |
# Check that npm is home
npm -v
poetry run bash scripts/integration.sh ./reflex-web prod
rx-shout-from-template:
strategy:
fail-fast: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: "3.11.11"
run-poetry-install: true
create-venv-at-path: .venv
- name: Create app directory
run: mkdir rx-shout-from-template
- name: Init reflex-web from template
run: poetry run reflex init --template https://github.com/masenf/rx_shout
working-directory: ./rx-shout-from-template
- name: ignore reflex pin in requirements
run: sed -i -e '/reflex==/d' requirements.txt
working-directory: ./rx-shout-from-template
- name: Install additional dependencies
run: poetry run uv pip install -r requirements.txt
working-directory: ./rx-shout-from-template
- name: Run Website and Check for errors
run: |
# Check that npm is home
npm -v
poetry run bash scripts/integration.sh ./rx-shout-from-template prod
reflex-web-macos:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
strategy:
fail-fast: false
matrix:
# Note: py311 version chosen due to available arm64 darwin builds.
python-version: ["3.11.9", "3.12.8"]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: ${{ matrix.python-version }}
run-poetry-install: true
create-venv-at-path: .venv
- name: Clone Reflex Website Repo
uses: actions/checkout@v4
with:
repository: reflex-dev/reflex-web
ref: main
path: reflex-web
- name: Install Requirements for reflex-web
working-directory: ./reflex-web
run: poetry run uv pip install -r requirements.txt
- name: Install additional dependencies for DB access
run: poetry run uv pip install psycopg
- name: Init Website for reflex-web
working-directory: ./reflex-web
run: poetry run reflex init
@ -145,11 +217,3 @@ jobs:
# Check that npm is home
npm -v
poetry run bash scripts/integration.sh ./reflex-web prod
- name: Measure and upload .web size
if: ${{ env.DATABASE_URL }}
run:
poetry run python scripts/benchmarks/benchmark_reflex_size.py --os "${{ matrix.os }}"
--python-version "${{ matrix.python-version }}" --commit-sha "${{ github.sha }}"
--pr-id "${{ github.event.pull_request.id }}"
--db-url "${{ env.DATABASE_URL }}" --branch-name "${{ github.head_ref || github.ref_name }}"
--measurement-type "reflex-web-dot-web" --path ./reflex-web/.web

View File

@ -37,6 +37,8 @@ jobs:
path: reflex-examples
- uses: Vampire/setup-wsl@v3
with:
distribution: Ubuntu-24.04
- name: Install Python
shell: wsl-bash {0}
@ -56,11 +58,16 @@ jobs:
run: |
poetry install
- name: Install uv
shell: wsl-bash {0}
run: |
poetry run pip install uv
- name: Install requirements for counter example
working-directory: ./reflex-examples/counter
shell: wsl-bash {0}
run: |
poetry run pip install -r requirements.txt
poetry run uv pip install -r requirements.txt
- name: Check export --backend-only before init for counter example
working-directory: ./reflex-examples/counter
shell: wsl-bash {0}

34
.github/workflows/performance.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: performance-tests
on:
push:
branches:
- "main" # or "master"
paths-ignore:
- "**/*.md"
pull_request:
workflow_dispatch:
env:
TELEMETRY_ENABLED: false
NODE_OPTIONS: "--max_old_space_size=8192"
PR_TITLE: ${{ github.event.pull_request.title }}
APP_HARNESS_HEADLESS: 1
PYTHONUNBUFFERED: 1
jobs:
benchmarks:
name: Run benchmarks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: 3.12.8
run-poetry-install: true
create-venv-at-path: .venv
- name: Run benchmarks
uses: CodSpeedHQ/action@v3
with:
token: ${{ secrets.CODSPEED_TOKEN }}
run: poetry run pytest tests/benchmarks --codspeed

View File

@ -6,12 +6,12 @@ concurrency:
on:
pull_request:
branches: ['main']
branches: ["main"]
push:
# Note even though this job is called "pre-commit" and runs "pre-commit", this job will run
# also POST-commit on main also! In case there are mishandled merge conflicts / bad auto-resolves
# when merging into main branch.
branches: ['main']
branches: ["main"]
jobs:
pre-commit:
@ -23,12 +23,12 @@ jobs:
with:
# running vs. one version of Python is OK
# i.e. ruff, black, etc.
python-version: 3.11.5
python-version: 3.12.8
run-poetry-install: true
create-venv-at-path: .venv
# TODO pre-commit related stuff can be cached too (not a bottleneck yet)
- run: |
poetry run pip install pre-commit
poetry run uv pip install pre-commit
poetry run pre-commit run --all-files
env:
SKIP: update-pyi-files

View File

@ -28,5 +28,5 @@ jobs:
# Run reflex init in a docker container
# cwd is repo root
docker build -f integration/init-test/Dockerfile -t reflex-init-test integration/init-test
docker run --rm -v $(pwd):/reflex-repo/ reflex-init-test /reflex-repo/integration/init-test/in_docker_test_script.sh
docker build -f tests/integration/init-test/Dockerfile -t reflex-init-test tests/integration/init-test
docker run --rm -v $(pwd):/reflex-repo/ reflex-init-test /reflex-repo/tests/integration/init-test/in_docker_test_script.sh

View File

@ -6,13 +6,13 @@ concurrency:
on:
push:
branches: ['main']
branches: ["main"]
paths-ignore:
- '**/*.md'
- "**/*.md"
pull_request:
branches: ['main']
branches: ["main"]
paths-ignore:
- '**/*.md'
- "**/*.md"
permissions:
contents: read
@ -27,24 +27,21 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-12]
python-version: ['3.8.18', '3.9.18', '3.10.13', '3.11.5', '3.12.0']
os: [ubuntu-latest, windows-latest]
python-version: ["3.10.16", "3.11.11", "3.12.8", "3.13.1"]
# Windows is a bit behind on Python version availability in Github
exclude:
- os: windows-latest
python-version: '3.10.13'
python-version: "3.11.11"
- os: windows-latest
python-version: '3.9.18'
- os: windows-latest
python-version: '3.8.18'
python-version: "3.10.16"
include:
- os: windows-latest
python-version: '3.10.11'
python-version: "3.11.9"
- os: windows-latest
python-version: '3.9.13'
- os: windows-latest
python-version: '3.8.10'
python-version: "3.10.11"
runs-on: ${{ matrix.os }}
# Service containers to run with `runner-job`
services:
# Label used to access the service container
@ -69,17 +66,44 @@ jobs:
- name: Run unit tests
run: |
export PYTHONUNBUFFERED=1
poetry run pytest tests --cov --no-cov-on-fail --cov-report=
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
- name: Run unit tests w/ redis
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
export PYTHONUNBUFFERED=1
export REDIS_URL=redis://localhost:6379
poetry run pytest tests --cov --no-cov-on-fail --cov-report=
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
# Change to explicitly install v1 when reflex-hosting-cli is compatible with v2
- name: Run unit tests w/ pydantic v1
run: |
export PYTHONUNBUFFERED=1
poetry run pip install "pydantic~=1.10"
poetry run pytest tests --cov --no-cov-on-fail --cov-report=
- run: poetry run coverage html
poetry run uv pip install "pydantic~=1.10"
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
- name: Generate coverage report
run: poetry run coverage html
unit-tests-macos:
timeout-minutes: 30
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
strategy:
fail-fast: false
matrix:
# Note: py310, py311 versions chosen due to available arm64 darwin builds.
python-version: ["3.10.11", "3.11.9", "3.12.8", "3.13.1"]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup_build_env
with:
python-version: ${{ matrix.python-version }}
run-poetry-install: true
create-venv-at-path: .venv
- name: Run unit tests
run: |
export PYTHONUNBUFFERED=1
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
- name: Run unit tests w/ pydantic v1
run: |
export PYTHONUNBUFFERED=1
poetry run uv pip install "pydantic~=1.10"
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=

5
.gitignore vendored
View File

@ -1,7 +1,10 @@
**/.DS_Store
**/*.pyc
assets/external/*
dist/*
examples/
.web
.states
.idea
.vscode
.coverage
@ -11,3 +14,5 @@ venv
requirements.txt
.pyi_generator_last_run
.pyi_generator_diff
reflex.db
.codspeed

View File

@ -3,19 +3,36 @@ fail_fast: true
repos:
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.1.0
rev: v0.9.6
hooks:
- id: ruff-format
args: [integration, reflex, tests]
args: [reflex, tests]
- id: ruff
args: ["--fix", "--exit-non-zero-on-fix"]
exclude: '^integration/benchmarks/'
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
args: ["reflex"]
# Run pyi check before pyright because pyright can fail if pyi files are wrong.
- repo: local
hooks:
- id: update-pyi-files
name: update-pyi-files
always_run: true
language: system
require_serial: true
description: 'Update pyi files as needed'
entry: python3 scripts/make_pyi.py
- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.313
rev: v1.1.393
hooks:
- id: pyright
args: [integration, reflex, tests]
args: [reflex, tests]
language: system
- repo: https://github.com/terrencepreilly/darglint
@ -24,11 +41,3 @@ repos:
- id: darglint
exclude: '^reflex/reflex.py'
- repo: local
hooks:
- id: update-pyi-files
name: update-pyi-files
always_run: true
language: system
description: 'Update pyi files as needed'
entry: python scripts/make_pyi.py

View File

@ -5,7 +5,7 @@
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
identity and expression, level of experience, education, socioeconomic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

View File

@ -8,7 +8,7 @@ Here is a quick guide on how to run Reflex repo locally so you can start contrib
**Prerequisites:**
- Python >= 3.8
- Python >= 3.10
- Poetry version >= 1.4.0 and add it to your path (see [Poetry Docs](https://python-poetry.org/docs/#installation) for more info).
**1. Fork this repository:**
@ -69,7 +69,7 @@ In your `reflex` directory run make sure all the unit tests are still passing us
This will fail if code coverage is below 70%.
``` bash
poetry run pytest tests --cov --no-cov-on-fail --cov-report=
poetry run pytest tests/units --cov --no-cov-on-fail --cov-report=
```
Next make sure all the following tests pass. This ensures that every new change has proper documentation and type checking.
@ -80,14 +80,14 @@ poetry run pyright reflex tests
find reflex tests -name "*.py" -not -path reflex/reflex.py | xargs poetry run darglint
```
Finally, run `black` to format your code.
Finally, run `ruff` to format your code.
``` bash
poetry run black reflex tests
poetry run ruff format .
```
Consider installing git pre-commit hooks so Ruff, Pyright, Darglint and Black will run automatically before each commit.
Note that pre-commit will only be installed when you use a Python version >= 3.8.
Consider installing git pre-commit hooks so Ruff, Pyright, Darglint and `make_pyi` will run automatically before each commit.
Note that pre-commit will only be installed when you use a Python version >= 3.10.
``` bash
pre-commit install

View File

@ -10,7 +10,6 @@
### **✨ Performant, customizable web apps in pure Python. Deploy in seconds. ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![tests](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentation](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
@ -18,7 +17,7 @@
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md)
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md) | [Tiếng Việt](https://github.com/reflex-dev/reflex/blob/main/docs/vi/README.md)
---
@ -35,7 +34,7 @@ See our [architecture page](https://reflex.dev/blog/2024-03-21-reflex-architectu
## ⚙️ Installation
Open a terminal and run (Requires Python 3.8+):
Open a terminal and run (Requires Python 3.10+):
```bash
pip install reflex
@ -120,14 +119,15 @@ def index():
on_blur=State.set_prompt,
width="25em",
),
rx.button("Generate Image", on_click=State.get_image, width="25em"),
rx.button(
"Generate Image",
on_click=State.get_image,
width="25em",
loading=State.processing
),
rx.cond(
State.processing,
rx.chakra.circular_progress(is_indeterminate=True),
rx.cond(
State.complete,
rx.image(src=State.image_url, width="20em"),
),
State.complete,
rx.image(src=State.image_url, width="20em"),
),
align="center",
),
@ -185,7 +185,7 @@ class State(rx.State):
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 show the circular progress and image.
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.
### **Event Handlers**
@ -228,7 +228,7 @@ You can create a multi-page app by adding more pages.
<div align="center">
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Gallery](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy-quick-start) &nbsp;
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Templates](https://reflex.dev/templates/) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy-quick-start) &nbsp;
</div>
@ -249,7 +249,7 @@ We welcome contributions of any size! Below are some good ways to get started in
- **GitHub Discussions**: A great way to talk about features you want added or things that are confusing/need clarification.
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/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 [CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
We are actively looking for contributors, no matter your skill level or experience. To contribute check out [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
## All Thanks To Our Contributors:

View File

@ -1,13 +1,13 @@
"""Runs the benchmarks and inserts the results into the database."""
"""Extracts the compile times from the JSON files in the specified directory and inserts them into the database."""
from __future__ import annotations
import argparse
import json
import os
from datetime import datetime
from pathlib import Path
import psycopg2
from utils import send_data_to_posthog
def extract_stats_from_json(json_file: str) -> list[dict]:
@ -19,7 +19,7 @@ def extract_stats_from_json(json_file: str) -> list[dict]:
Returns:
list[dict]: The stats for each test.
"""
with open(json_file, "r") as file:
with Path(json_file).open() as file:
json_data = json.load(file)
# Load the JSON data if it is a string, otherwise assume it's already a dictionary
@ -51,7 +51,6 @@ def extract_stats_from_json(json_file: str) -> list[dict]:
def insert_benchmarking_data(
db_connection_url: str,
os_type_version: str,
python_version: str,
performance_data: list[dict],
@ -59,52 +58,33 @@ def insert_benchmarking_data(
pr_title: str,
branch_name: str,
event_type: str,
actor: str,
pr_id: str,
):
"""Insert the benchmarking data into the database.
Args:
db_connection_url: The URL to connect to the database.
os_type_version: The OS type and version to insert.
python_version: The Python version to insert.
performance_data: The performance data of reflex web to insert.
commit_sha: The commit SHA to insert.
pr_title: The PR title to insert.
branch_name: The name of the branch.
event_type: Type of github event(push, pull request, etc)
actor: Username of the user that triggered the run.
event_type: Type of github event(push, pull request, etc).
pr_id: Id of the PR.
"""
# Serialize the JSON data
simple_app_performance_json = json.dumps(performance_data)
# Prepare the event data
properties = {
"os": os_type_version,
"python_version": python_version,
"distinct_id": commit_sha,
"pr_title": pr_title,
"branch_name": branch_name,
"event_type": event_type,
"performance": performance_data,
"pr_id": pr_id,
}
# Get the current timestamp
current_timestamp = datetime.now()
# Connect to the database and insert the data
with psycopg2.connect(db_connection_url) as conn, conn.cursor() as cursor:
insert_query = """
INSERT INTO simple_app_benchmarks (os, python_version, commit_sha, time, pr_title, branch_name, event_type, actor, performance, pr_id)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s);
"""
cursor.execute(
insert_query,
(
os_type_version,
python_version,
commit_sha,
current_timestamp,
pr_title,
branch_name,
event_type,
actor,
simple_app_performance_json,
pr_id,
),
)
# Commit the transaction
conn.commit()
send_data_to_posthog("simple_app_benchmark", properties)
def main():
@ -124,11 +104,6 @@ def main():
"--benchmark-json",
help="The JSON file containing the benchmark results.",
)
parser.add_argument(
"--db-url",
help="The URL to connect to the database.",
required=True,
)
parser.add_argument(
"--pr-title",
help="The PR title to insert into the database.",
@ -143,11 +118,6 @@ def main():
help="The github event type",
required=True,
)
parser.add_argument(
"--actor",
help="Username of the user that triggered the run.",
required=True,
)
parser.add_argument(
"--pr-id",
help="ID of the PR.",
@ -162,7 +132,6 @@ def main():
cleaned_benchmark_results = extract_stats_from_json(args.benchmark_json)
# Insert the data into the database
insert_benchmarking_data(
db_connection_url=args.db_url,
os_type_version=args.os,
python_version=args.python_version,
performance_data=cleaned_benchmark_results,
@ -170,7 +139,6 @@ def main():
pr_title=pr_title,
branch_name=args.branch_name,
event_type=args.event_type,
actor=args.actor,
pr_id=args.pr_id,
)

View File

@ -0,0 +1,128 @@
"""Extract and upload benchmarking data to PostHog."""
from __future__ import annotations
import argparse
import json
import os
from pathlib import Path
from utils import send_data_to_posthog
def extract_stats_from_json(json_file: str) -> dict:
"""Extracts the stats from the JSON data and returns them as dictionaries.
Args:
json_file: The JSON file to extract the stats data from.
Returns:
dict: The stats for each test.
"""
with Path(json_file).open() as file:
json_data = json.load(file)
# Load the JSON data if it is a string, otherwise assume it's already a dictionary
data = json.loads(json_data) if isinstance(json_data, str) else json_data
result = data.get("results", [{}])[0]
return {
k: v
for k, v in result.items()
if k in ("mean", "stddev", "median", "min", "max")
}
def insert_benchmarking_data(
os_type_version: str,
python_version: str,
performance_data: dict,
commit_sha: str,
pr_title: str,
branch_name: str,
pr_id: str,
app_name: str,
):
"""Insert the benchmarking data into the database.
Args:
os_type_version: The OS type and version to insert.
python_version: The Python version to insert.
performance_data: The imports performance data to insert.
commit_sha: The commit SHA to insert.
pr_title: The PR title to insert.
branch_name: The name of the branch.
pr_id: Id of the PR.
app_name: The name of the app being measured.
"""
properties = {
"os": os_type_version,
"python_version": python_version,
"distinct_id": commit_sha,
"pr_title": pr_title,
"branch_name": branch_name,
"pr_id": pr_id,
"performance": performance_data,
"app_name": app_name,
}
send_data_to_posthog("import_benchmark", properties)
def main():
"""Runs the benchmarks and inserts the results."""
# Get the commit SHA and JSON directory from the command line arguments
parser = argparse.ArgumentParser(description="Run benchmarks and process results.")
parser.add_argument(
"--os", help="The OS type and version to insert into the database."
)
parser.add_argument(
"--python-version", help="The Python version to insert into the database."
)
parser.add_argument(
"--commit-sha", help="The commit SHA to insert into the database."
)
parser.add_argument(
"--benchmark-json",
help="The JSON file containing the benchmark results.",
)
parser.add_argument(
"--pr-title",
help="The PR title to insert into the database.",
)
parser.add_argument(
"--branch-name",
help="The current branch",
required=True,
)
parser.add_argument(
"--app-name",
help="The name of the app measured.",
required=True,
)
parser.add_argument(
"--pr-id",
help="ID of the PR.",
required=True,
)
args = parser.parse_args()
# Get the PR title from env or the args. For the PR merge or push event, there is no PR title, leaving it empty.
pr_title = args.pr_title or os.getenv("PR_TITLE", "")
cleaned_benchmark_results = extract_stats_from_json(args.benchmark_json)
# Insert the data into the database
insert_benchmarking_data(
os_type_version=args.os,
python_version=args.python_version,
performance_data=cleaned_benchmark_results,
commit_sha=args.commit_sha,
pr_title=pr_title,
branch_name=args.branch_name,
app_name=args.app_name,
pr_id=args.pr_id,
)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,75 @@
"""Extracts the Lighthouse scores from the JSON files in the specified directory and inserts them into the database."""
from __future__ import annotations
import json
import sys
from pathlib import Path
from utils import send_data_to_posthog
def insert_benchmarking_data(
lighthouse_data: dict,
commit_sha: str,
):
"""Insert the benchmarking data into the database.
Args:
lighthouse_data: The Lighthouse data to insert.
commit_sha: The commit SHA to insert.
"""
properties = {
"distinct_id": commit_sha,
"lighthouse_data": lighthouse_data,
}
# Send the data to PostHog
send_data_to_posthog("lighthouse_benchmark", properties)
def get_lighthouse_scores(directory_path: str | Path) -> dict:
"""Extracts the Lighthouse scores from the JSON files in the specified directory.
Args:
directory_path (str): The path to the directory containing the JSON files.
Returns:
dict: The Lighthouse scores.
"""
scores = {}
directory_path = Path(directory_path)
try:
for filename in directory_path.iterdir():
if filename.suffix == ".json" and filename.stem != "manifest":
data = json.loads(filename.read_text())
# Extract scores and add them to the dictionary with the filename as key
scores[data["finalUrl"].replace("http://localhost:3000/", "/")] = {
"performance_score": data["categories"]["performance"]["score"],
"accessibility_score": data["categories"]["accessibility"]["score"],
"best_practices_score": data["categories"]["best-practices"][
"score"
],
"seo_score": data["categories"]["seo"]["score"],
}
except Exception as e:
return {"error": e}
return scores
def main():
"""Runs the benchmarks and inserts the results into the database."""
# Get the commit SHA and JSON directory from the command line arguments
commit_sha = sys.argv[1]
json_dir = sys.argv[2]
# Get the Lighthouse scores
lighthouse_scores = get_lighthouse_scores(json_dir)
# Insert the data into the database
insert_benchmarking_data(lighthouse_scores, commit_sha)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,135 @@
"""Checks the size of a specific directory and uploads result to Posthog."""
import argparse
import os
from pathlib import Path
from utils import get_directory_size, get_python_version, send_data_to_posthog
def get_package_size(venv_path: Path, os_name):
"""Get the size of a specified package.
Args:
venv_path: The path to the venv.
os_name: Name of os.
Returns:
The total size of the package in bytes.
Raises:
ValueError: when venv does not exist or python version is None.
"""
python_version = get_python_version(venv_path, os_name)
print("Python version:", python_version)
if python_version is None:
raise ValueError("Error: Failed to determine Python version.")
is_windows = "windows" in os_name
package_dir: Path = (
venv_path / "lib" / f"python{python_version}" / "site-packages"
if not is_windows
else venv_path / "Lib" / "site-packages"
)
if not package_dir.exists():
raise ValueError(
"Error: Virtual environment does not exist or is not activated."
)
total_size = get_directory_size(package_dir)
return total_size
def insert_benchmarking_data(
os_type_version: str,
python_version: str,
commit_sha: str,
pr_title: str,
branch_name: str,
pr_id: str,
path: str,
):
"""Insert the benchmarking data into PostHog.
Args:
os_type_version: The OS type and version to insert.
python_version: The Python version to insert.
commit_sha: The commit SHA to insert.
pr_title: The PR title to insert.
branch_name: The name of the branch.
pr_id: The id of the PR.
path: The path to the dir or file to check size.
"""
if "./dist" in path:
size = get_directory_size(Path(path))
else:
size = get_package_size(Path(path), os_type_version)
# Prepare the event data
properties = {
"path": path,
"os": os_type_version,
"python_version": python_version,
"distinct_id": commit_sha,
"pr_title": pr_title,
"branch_name": branch_name,
"pr_id": pr_id,
"size_mb": round(
size / (1024 * 1024), 3
), # save size in MB and round to 3 places
}
send_data_to_posthog("package_size", properties)
def main():
"""Runs the benchmarks and inserts the results."""
parser = argparse.ArgumentParser(description="Run benchmarks and process results.")
parser.add_argument(
"--os", help="The OS type and version to insert into the database."
)
parser.add_argument(
"--python-version", help="The Python version to insert into the database."
)
parser.add_argument(
"--commit-sha", help="The commit SHA to insert into the database."
)
parser.add_argument(
"--pr-title",
help="The PR title to insert into the database.",
)
parser.add_argument(
"--branch-name",
help="The current branch",
required=True,
)
parser.add_argument(
"--pr-id",
help="The pr id",
required=True,
)
parser.add_argument(
"--path",
help="The path to the vnenv.",
required=True,
)
args = parser.parse_args()
# Get the PR title from env or the args. For the PR merge or push event, there is no PR title, leaving it empty.
pr_title = args.pr_title or os.getenv("PR_TITLE", "")
# Insert the data into the database
insert_benchmarking_data(
os_type_version=args.os,
python_version=args.python_version,
commit_sha=args.commit_sha,
pr_title=pr_title,
branch_name=args.branch_name,
pr_id=args.pr_id,
path=args.path,
)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,106 @@
"""Checks the size of a specific directory and uploads result to Posthog."""
import argparse
import os
from pathlib import Path
from utils import get_directory_size, send_data_to_posthog
def insert_benchmarking_data(
os_type_version: str,
python_version: str,
app_name: str,
commit_sha: str,
pr_title: str,
branch_name: str,
pr_id: str,
path: str,
):
"""Insert the benchmarking data into PostHog.
Args:
app_name: The name of the app being measured.
os_type_version: The OS type and version to insert.
python_version: The Python version to insert.
commit_sha: The commit SHA to insert.
pr_title: The PR title to insert.
branch_name: The name of the branch.
pr_id: The id of the PR.
path: The path to the dir or file to check size.
"""
size = get_directory_size(Path(path))
# Prepare the event data
properties = {
"app_name": app_name,
"os": os_type_version,
"python_version": python_version,
"distinct_id": commit_sha,
"pr_title": pr_title,
"branch_name": branch_name,
"pr_id": pr_id,
"size_mb": round(
size / (1024 * 1024), 3
), # save size in MB and round to 3 places
}
send_data_to_posthog("web-size", properties)
def main():
"""Runs the benchmarks and inserts the results."""
parser = argparse.ArgumentParser(description="Run benchmarks and process results.")
parser.add_argument(
"--os", help="The OS type and version to insert into the database."
)
parser.add_argument(
"--python-version", help="The Python version to insert into the database."
)
parser.add_argument(
"--commit-sha", help="The commit SHA to insert into the database."
)
parser.add_argument(
"--pr-title",
help="The PR title to insert into the database.",
)
parser.add_argument(
"--branch-name",
help="The current branch",
required=True,
)
parser.add_argument(
"--app-name",
help="The name of the app measured.",
required=True,
)
parser.add_argument(
"--pr-id",
help="The pr id",
required=True,
)
parser.add_argument(
"--path",
help="The current path to app to check.",
required=True,
)
args = parser.parse_args()
# Get the PR title from env or the args. For the PR merge or push event, there is no PR title, leaving it empty.
pr_title = args.pr_title or os.getenv("PR_TITLE", "")
# Insert the data into the database
insert_benchmarking_data(
app_name=args.app_name,
os_type_version=args.os,
python_version=args.python_version,
commit_sha=args.commit_sha,
pr_title=pr_title,
branch_name=args.branch_name,
pr_id=args.pr_id,
path=args.path,
)
if __name__ == "__main__":
main()

View File

@ -1,373 +0,0 @@
"""Benchmark tests for apps with varying component numbers."""
from __future__ import annotations
import functools
import time
from typing import Generator
import pytest
from benchmarks import WINDOWS_SKIP_REASON
from reflex import constants
from reflex.compiler import utils
from reflex.testing import AppHarness, chdir
from reflex.utils import build
def render_component(num: int):
"""Generate a number of components based on num.
Args:
num: number of components to produce.
Returns:
The rendered number of components.
"""
import reflex as rx
return [
rx.fragment(
rx.box(
rx.accordion.root(
rx.accordion.item(
header="Full Ingredients", # type: ignore
content="Yes. It's built with accessibility in mind.", # type: ignore
font_size="3em",
),
rx.accordion.item(
header="Applications", # type: ignore
content="Yes. It's unstyled by default, giving you freedom over the look and feel.", # type: ignore
),
collapsible=True,
variant="ghost",
width="25rem",
),
padding_top="20px",
),
rx.box(
rx.drawer.root(
rx.drawer.trigger(
rx.button("Open Drawer with snap points"), as_child=True
),
rx.drawer.overlay(),
rx.drawer.portal(
rx.drawer.content(
rx.flex(
rx.drawer.title("Drawer Content"),
rx.drawer.description("Drawer description"),
rx.drawer.close(
rx.button("Close Button"),
as_child=True,
),
direction="column",
margin="5em",
align_items="center",
),
top="auto",
height="100%",
flex_direction="column",
background_color="var(--green-3)",
),
),
snap_points=["148px", "355px", 1],
),
),
rx.box(
rx.callout(
"You will need admin privileges to install and access this application.",
icon="info",
size="3",
),
),
rx.box(
rx.table.root(
rx.table.header(
rx.table.row(
rx.table.column_header_cell("Full name"),
rx.table.column_header_cell("Email"),
rx.table.column_header_cell("Group"),
),
),
rx.table.body(
rx.table.row(
rx.table.row_header_cell("Danilo Sousa"),
rx.table.cell("danilo@example.com"),
rx.table.cell("Developer"),
),
rx.table.row(
rx.table.row_header_cell("Zahra Ambessa"),
rx.table.cell("zahra@example.com"),
rx.table.cell("Admin"),
),
rx.table.row(
rx.table.row_header_cell("Jasper Eriksson"),
rx.table.cell("jasper@example.com"),
rx.table.cell("Developer"),
),
),
)
),
)
] * num
def AppWithTenComponentsOnePage():
"""A reflex app with roughly 10 components on one page."""
import reflex as rx
def index() -> rx.Component:
return rx.center(rx.vstack(*render_component(1)))
app = rx.App(state=rx.State)
app.add_page(index)
def AppWithHundredComponentOnePage():
"""A reflex app with roughly 100 components on one page."""
import reflex as rx
def index() -> rx.Component:
return rx.center(rx.vstack(*render_component(100)))
app = rx.App(state=rx.State)
app.add_page(index)
def AppWithThousandComponentsOnePage():
"""A reflex app with roughly 1000 components on one page."""
import reflex as rx
def index() -> rx.Component:
return rx.center(rx.vstack(*render_component(1000)))
app = rx.App(state=rx.State)
app.add_page(index)
@pytest.fixture(scope="session")
def app_with_10_components(
tmp_path_factory,
) -> Generator[AppHarness, None, None]:
"""Start Blank Template app at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
running AppHarness instance
"""
root = tmp_path_factory.mktemp("app10components")
yield AppHarness.create(
root=root,
app_source=functools.partial(
AppWithTenComponentsOnePage,
render_component=render_component, # type: ignore
),
) # type: ignore
@pytest.fixture(scope="session")
def app_with_100_components(
tmp_path_factory,
) -> Generator[AppHarness, None, None]:
"""Start Blank Template app at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
running AppHarness instance
"""
root = tmp_path_factory.mktemp("app100components")
yield AppHarness.create(
root=root,
app_source=functools.partial(
AppWithHundredComponentOnePage,
render_component=render_component, # type: ignore
),
) # type: ignore
@pytest.fixture(scope="session")
def app_with_1000_components(
tmp_path_factory,
) -> Generator[AppHarness, None, None]:
"""Create an app with 1000 components at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
an AppHarness instance
"""
root = tmp_path_factory.mktemp("app1000components")
yield AppHarness.create(
root=root,
app_source=functools.partial(
AppWithThousandComponentsOnePage,
render_component=render_component, # type: ignore
),
) # type: ignore
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
@pytest.mark.benchmark(
group="Compile time of varying component numbers",
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_10_compile_time_cold(benchmark, app_with_10_components):
"""Test the compile time on a cold start for an app with roughly 10 components.
Args:
benchmark: The benchmark fixture.
app_with_10_components: The app harness.
"""
def setup():
with chdir(app_with_10_components.app_path):
utils.empty_dir(constants.Dirs.WEB_PAGES, keep_files=["_app.js"])
app_with_10_components._initialize_app()
build.setup_frontend(app_with_10_components.app_path)
def benchmark_fn():
with chdir(app_with_10_components.app_path):
app_with_10_components.app_instance._compile()
benchmark.pedantic(benchmark_fn, setup=setup, rounds=10)
@pytest.mark.benchmark(
group="Compile time of varying component numbers",
min_rounds=5,
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_10_compile_time_warm(benchmark, app_with_10_components):
"""Test the compile time on a warm start for an app with roughly 10 components.
Args:
benchmark: The benchmark fixture.
app_with_10_components: The app harness.
"""
with chdir(app_with_10_components.app_path):
app_with_10_components._initialize_app()
build.setup_frontend(app_with_10_components.app_path)
def benchmark_fn():
with chdir(app_with_10_components.app_path):
app_with_10_components.app_instance._compile()
benchmark(benchmark_fn)
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
@pytest.mark.benchmark(
group="Compile time of varying component numbers",
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_100_compile_time_cold(benchmark, app_with_100_components):
"""Test the compile time on a cold start for an app with roughly 100 components.
Args:
benchmark: The benchmark fixture.
app_with_100_components: The app harness.
"""
def setup():
with chdir(app_with_100_components.app_path):
utils.empty_dir(constants.Dirs.WEB_PAGES, keep_files=["_app.js"])
app_with_100_components._initialize_app()
build.setup_frontend(app_with_100_components.app_path)
def benchmark_fn():
with chdir(app_with_100_components.app_path):
app_with_100_components.app_instance._compile()
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
@pytest.mark.benchmark(
group="Compile time of varying component numbers",
min_rounds=5,
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_100_compile_time_warm(benchmark, app_with_100_components):
"""Test the compile time on a warm start for an app with roughly 100 components.
Args:
benchmark: The benchmark fixture.
app_with_100_components: The app harness.
"""
with chdir(app_with_100_components.app_path):
app_with_100_components._initialize_app()
build.setup_frontend(app_with_100_components.app_path)
def benchmark_fn():
with chdir(app_with_100_components.app_path):
app_with_100_components.app_instance._compile()
benchmark(benchmark_fn)
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
@pytest.mark.benchmark(
group="Compile time of varying component numbers",
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_1000_compile_time_cold(benchmark, app_with_1000_components):
"""Test the compile time on a cold start for an app with roughly 1000 components.
Args:
benchmark: The benchmark fixture.
app_with_1000_components: The app harness.
"""
def setup():
with chdir(app_with_1000_components.app_path):
utils.empty_dir(constants.Dirs.WEB_PAGES, keep_files=["_app.js"])
app_with_1000_components._initialize_app()
build.setup_frontend(app_with_1000_components.app_path)
def benchmark_fn():
with chdir(app_with_1000_components.app_path):
app_with_1000_components.app_instance._compile()
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
@pytest.mark.benchmark(
group="Compile time of varying component numbers",
min_rounds=5,
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_1000_compile_time_warm(benchmark, app_with_1000_components):
"""Test the compile time on a warm start for an app with roughly 1000 components.
Args:
benchmark: The benchmark fixture.
app_with_1000_components: The app harness.
"""
with chdir(app_with_1000_components.app_path):
app_with_1000_components._initialize_app()
build.setup_frontend(app_with_1000_components.app_path)
def benchmark_fn():
with chdir(app_with_1000_components.app_path):
app_with_1000_components.app_instance._compile()
benchmark(benchmark_fn)

View File

@ -1,576 +0,0 @@
"""Benchmark tests for apps with varying page numbers."""
from __future__ import annotations
import functools
import time
from typing import Generator
import pytest
from benchmarks import WINDOWS_SKIP_REASON
from reflex import constants
from reflex.compiler import utils
from reflex.testing import AppHarness, chdir
from reflex.utils import build
def render_multiple_pages(app, num: int):
"""Add multiple pages based on num.
Args:
app: The App object.
num: number of pages to render.
"""
from typing import Tuple
from rxconfig import config # type: ignore
import reflex as rx
docs_url = "https://reflex.dev/docs/getting-started/introduction/"
filename = f"{config.app_name}/{config.app_name}.py"
college = [
"Stanford University",
"Arizona",
"Arizona state",
"Baylor",
"Boston College",
"Boston University",
]
class State(rx.State):
"""The app state."""
position: str
college: str
age: Tuple[int, int] = (18, 50)
salary: Tuple[int, int] = (0, 25000000)
comp1 = rx.center(
rx.theme_panel(),
rx.vstack(
rx.heading("Welcome to Reflex!", size="9"),
rx.text("Get started by editing ", rx.code(filename)),
rx.button(
"Check out our docs!",
on_click=lambda: rx.redirect(docs_url),
size="4",
),
align="center",
spacing="7",
font_size="2em",
),
height="100vh",
)
comp2 = rx.vstack(
rx.hstack(
rx.vstack(
rx.select(
["C", "PF", "SF", "PG", "SG"],
placeholder="Select a position. (All)",
on_change=State.set_position, # type: ignore
size="3",
),
rx.select(
college,
placeholder="Select a college. (All)",
on_change=State.set_college, # type: ignore
size="3",
),
),
rx.vstack(
rx.vstack(
rx.hstack(
rx.badge("Min Age: ", State.age[0]),
rx.divider(orientation="vertical"),
rx.badge("Max Age: ", State.age[1]),
),
rx.slider(
default_value=[18, 50],
min=18,
max=50,
on_value_commit=State.set_age, # type: ignore
),
align_items="left",
width="100%",
),
rx.vstack(
rx.hstack(
rx.badge("Min Sal: ", State.salary[0] // 1000000, "M"),
rx.divider(orientation="vertical"),
rx.badge("Max Sal: ", State.salary[1] // 1000000, "M"),
),
rx.slider(
default_value=[0, 25000000],
min=0,
max=25000000,
on_value_commit=State.set_salary, # type: ignore
),
align_items="left",
width="100%",
),
),
spacing="4",
),
width="100%",
)
for i in range(1, num + 1):
if i % 2 == 1:
app.add_page(comp1, route=f"page{i}")
else:
app.add_page(comp2, route=f"page{i}")
def AppWithOnePage():
"""A reflex app with one page."""
from rxconfig import config # type: ignore
import reflex as rx
docs_url = "https://reflex.dev/docs/getting-started/introduction/"
filename = f"{config.app_name}/{config.app_name}.py"
class State(rx.State):
"""The app state."""
pass
def index() -> rx.Component:
return rx.center(
rx.chakra.input(
id="token", value=State.router.session.client_token, is_read_only=True
),
rx.vstack(
rx.heading("Welcome to Reflex!", size="9"),
rx.text("Get started by editing ", rx.code(filename)),
rx.button(
"Check out our docs!",
on_click=lambda: rx.redirect(docs_url),
size="4",
),
align="center",
spacing="7",
font_size="2em",
),
height="100vh",
)
app = rx.App(state=rx.State)
app.add_page(index)
def AppWithTenPages():
"""A reflex app with 10 pages."""
import reflex as rx
app = rx.App(state=rx.State)
render_multiple_pages(app, 10)
def AppWithHundredPages():
"""A reflex app with 100 pages."""
import reflex as rx
app = rx.App(state=rx.State)
render_multiple_pages(app, 100)
def AppWithThousandPages():
"""A reflex app with Thousand pages."""
import reflex as rx
app = rx.App(state=rx.State)
render_multiple_pages(app, 1000)
def AppWithTenThousandPages():
"""A reflex app with ten thousand pages."""
import reflex as rx
app = rx.App(state=rx.State)
render_multiple_pages(app, 10000)
@pytest.fixture(scope="session")
def app_with_one_page(
tmp_path_factory,
) -> Generator[AppHarness, None, None]:
"""Create an app with 10000 pages at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
an AppHarness instance
"""
root = tmp_path_factory.mktemp(f"app1")
yield AppHarness.create(root=root, app_source=AppWithOnePage) # type: ignore
@pytest.fixture(scope="session")
def app_with_ten_pages(
tmp_path_factory,
) -> Generator[AppHarness, None, None]:
"""Create an app with 10 pages at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
an AppHarness instance
"""
root = tmp_path_factory.mktemp(f"app10")
yield AppHarness.create(
root=root,
app_source=functools.partial(
AppWithTenPages,
render_comp=render_multiple_pages, # type: ignore
),
)
@pytest.fixture(scope="session")
def app_with_hundred_pages(
tmp_path_factory,
) -> Generator[AppHarness, None, None]:
"""Create an app with 100 pages at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
an AppHarness instance
"""
root = tmp_path_factory.mktemp(f"app100")
yield AppHarness.create(
root=root,
app_source=functools.partial(
AppWithHundredPages,
render_comp=render_multiple_pages, # type: ignore
),
) # type: ignore
@pytest.fixture(scope="session")
def app_with_thousand_pages(
tmp_path_factory,
) -> Generator[AppHarness, None, None]:
"""Create an app with 1000 pages at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
an AppHarness instance
"""
root = tmp_path_factory.mktemp(f"app1000")
yield AppHarness.create(
root=root,
app_source=functools.partial( # type: ignore
AppWithThousandPages,
render_comp=render_multiple_pages, # type: ignore
),
) # type: ignore
@pytest.fixture(scope="session")
def app_with_ten_thousand_pages(
tmp_path_factory,
) -> Generator[AppHarness, None, None]:
"""Create an app with 10000 pages at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
running AppHarness instance
"""
root = tmp_path_factory.mktemp(f"app10000")
yield AppHarness.create(
root=root,
app_source=functools.partial(
AppWithTenThousandPages,
render_comp=render_multiple_pages, # type: ignore
),
) # type: ignore
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_1_compile_time_cold(benchmark, app_with_one_page):
"""Test the compile time on a cold start for an app with 1 page.
Args:
benchmark: The benchmark fixture.
app_with_one_page: The app harness.
"""
def setup():
with chdir(app_with_one_page.app_path):
utils.empty_dir(constants.Dirs.WEB_PAGES, keep_files=["_app.js"])
app_with_one_page._initialize_app()
build.setup_frontend(app_with_one_page.app_path)
def benchmark_fn():
with chdir(app_with_one_page.app_path):
app_with_one_page.app_instance._compile()
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
app_with_one_page._reload_state_module()
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
min_rounds=5,
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_1_compile_time_warm(benchmark, app_with_one_page):
"""Test the compile time on a warm start for an app with 1 page.
Args:
benchmark: The benchmark fixture.
app_with_one_page: The app harness.
"""
with chdir(app_with_one_page.app_path):
app_with_one_page._initialize_app()
build.setup_frontend(app_with_one_page.app_path)
def benchmark_fn():
with chdir(app_with_one_page.app_path):
app_with_one_page.app_instance._compile()
benchmark(benchmark_fn)
app_with_one_page._reload_state_module()
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_10_compile_time_cold(benchmark, app_with_ten_pages):
"""Test the compile time on a cold start for an app with 10 page.
Args:
benchmark: The benchmark fixture.
app_with_ten_pages: The app harness.
"""
def setup():
with chdir(app_with_ten_pages.app_path):
utils.empty_dir(constants.Dirs.WEB_PAGES, keep_files=["_app.js"])
app_with_ten_pages._initialize_app()
build.setup_frontend(app_with_ten_pages.app_path)
def benchmark_fn():
with chdir(app_with_ten_pages.app_path):
app_with_ten_pages.app_instance._compile()
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
app_with_ten_pages._reload_state_module()
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
min_rounds=5,
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_10_compile_time_warm(benchmark, app_with_ten_pages):
"""Test the compile time on a warm start for an app with 10 page.
Args:
benchmark: The benchmark fixture.
app_with_ten_pages: The app harness.
"""
with chdir(app_with_ten_pages.app_path):
app_with_ten_pages._initialize_app()
build.setup_frontend(app_with_ten_pages.app_path)
def benchmark_fn():
with chdir(app_with_ten_pages.app_path):
app_with_ten_pages.app_instance._compile()
benchmark(benchmark_fn)
app_with_ten_pages._reload_state_module()
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_100_compile_time_cold(benchmark, app_with_hundred_pages):
"""Test the compile time on a cold start for an app with 100 page.
Args:
benchmark: The benchmark fixture.
app_with_hundred_pages: The app harness.
"""
def setup():
with chdir(app_with_hundred_pages.app_path):
utils.empty_dir(constants.Dirs.WEB_PAGES, keep_files=["_app.js"])
app_with_hundred_pages._initialize_app()
build.setup_frontend(app_with_hundred_pages.app_path)
def benchmark_fn():
with chdir(app_with_hundred_pages.app_path):
app_with_hundred_pages.app_instance._compile()
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
app_with_hundred_pages._reload_state_module()
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
min_rounds=5,
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_100_compile_time_warm(benchmark, app_with_hundred_pages):
"""Test the compile time on a warm start for an app with 100 page.
Args:
benchmark: The benchmark fixture.
app_with_hundred_pages: The app harness.
"""
with chdir(app_with_hundred_pages.app_path):
app_with_hundred_pages._initialize_app()
build.setup_frontend(app_with_hundred_pages.app_path)
def benchmark_fn():
with chdir(app_with_hundred_pages.app_path):
app_with_hundred_pages.app_instance._compile()
benchmark(benchmark_fn)
app_with_hundred_pages._reload_state_module()
@pytest.mark.skipif(constants.IS_WINDOWS, reason=WINDOWS_SKIP_REASON)
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_1000_compile_time_cold(benchmark, app_with_thousand_pages):
"""Test the compile time on a cold start for an app with 1000 page.
Args:
benchmark: The benchmark fixture.
app_with_thousand_pages: The app harness.
"""
def setup():
with chdir(app_with_thousand_pages.app_path):
utils.empty_dir(constants.Dirs.WEB_PAGES, keep_files=["_app.js"])
app_with_thousand_pages._initialize_app()
build.setup_frontend(app_with_thousand_pages.app_path)
def benchmark_fn():
with chdir(app_with_thousand_pages.app_path):
app_with_thousand_pages.app_instance._compile()
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
app_with_thousand_pages._reload_state_module()
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
min_rounds=5,
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_1000_compile_time_warm(benchmark, app_with_thousand_pages):
"""Test the compile time on a warm start for an app with 1000 page.
Args:
benchmark: The benchmark fixture.
app_with_thousand_pages: The app harness.
"""
with chdir(app_with_thousand_pages.app_path):
app_with_thousand_pages._initialize_app()
build.setup_frontend(app_with_thousand_pages.app_path)
def benchmark_fn():
with chdir(app_with_thousand_pages.app_path):
app_with_thousand_pages.app_instance._compile()
benchmark(benchmark_fn)
app_with_thousand_pages._reload_state_module()
@pytest.mark.skip
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_10000_compile_time_cold(benchmark, app_with_ten_thousand_pages):
"""Test the compile time on a cold start for an app with 10000 page.
Args:
benchmark: The benchmark fixture.
app_with_ten_thousand_pages: The app harness.
"""
def setup():
with chdir(app_with_ten_thousand_pages.app_path):
utils.empty_dir(constants.Dirs.WEB_PAGES, keep_files=["_app.js"])
app_with_ten_thousand_pages._initialize_app()
build.setup_frontend(app_with_ten_thousand_pages.app_path)
def benchmark_fn():
with chdir(app_with_ten_thousand_pages.app_path):
app_with_ten_thousand_pages.app_instance._compile()
benchmark.pedantic(benchmark_fn, setup=setup, rounds=5)
app_with_ten_thousand_pages._reload_state_module()
@pytest.mark.skip
@pytest.mark.benchmark(
group="Compile time of varying page numbers",
min_rounds=5,
timer=time.perf_counter,
disable_gc=True,
warmup=False,
)
def test_app_10000_compile_time_warm(benchmark, app_with_ten_thousand_pages):
"""Test the compile time on a warm start for an app with 10000 page.
Args:
benchmark: The benchmark fixture.
app_with_ten_thousand_pages: The app harness.
"""
def benchmark_fn():
with chdir(app_with_ten_thousand_pages.app_path):
app_with_ten_thousand_pages.app_instance._compile()
benchmark(benchmark_fn)
app_with_ten_thousand_pages._reload_state_module()

74
benchmarks/utils.py Normal file
View File

@ -0,0 +1,74 @@
"""Utility functions for the benchmarks."""
import os
import subprocess
from pathlib import Path
import httpx
from httpx import HTTPError
def get_python_version(venv_path: Path, os_name):
"""Get the python version of python in a virtual env.
Args:
venv_path: Path to virtual environment.
os_name: Name of os.
Returns:
The python version.
"""
python_executable = (
venv_path / "bin" / "python"
if "windows" not in os_name
else venv_path / "Scripts" / "python.exe"
)
try:
output = subprocess.check_output(
[str(python_executable), "--version"], stderr=subprocess.STDOUT
)
python_version = output.decode("utf-8").strip().split()[1]
return ".".join(python_version.split(".")[:-1])
except subprocess.CalledProcessError:
return None
def get_directory_size(directory: Path):
"""Get the size of a directory in bytes.
Args:
directory: The directory to check.
Returns:
The size of the dir in bytes.
"""
total_size = 0
for dirpath, _, filenames in os.walk(directory):
for f in filenames:
fp = Path(dirpath) / f
total_size += fp.stat().st_size
return total_size
def send_data_to_posthog(event, properties):
"""Send data to PostHog.
Args:
event: The event to send.
properties: The properties to send.
Raises:
HTTPError: When there is an error sending data to PostHog.
"""
event_data = {
"api_key": "phc_JoMo0fOyi0GQAooY3UyO9k0hebGkMyFJrrCw1Gt5SGb",
"event": event,
"properties": properties,
}
with httpx.Client() as client:
response = client.post("https://app.posthog.com/capture/", json=event_data)
if response.status_code != 200:
raise HTTPError(
f"Error sending data to PostHog: {response.status_code} - {response.text}"
)

View File

@ -1,133 +1,30 @@
# Reflex Docker Container
# Reflex Docker Examples
This example describes how to create and use a container image for Reflex with your own code.
This directory contains several examples of how to deploy Reflex apps using docker.
## Update Requirements
In all cases, ensure that your `requirements.txt` file is up to date and
includes the `reflex` package.
The `requirements.txt` includes the reflex package which is needed to install
Reflex framework. If you use additional packages in your project you have to add
this in the `requirements.txt` first. Copy the `Dockerfile`, `.dockerignore` and
the `requirements.txt` file in your project folder.
## `simple-two-port`
## Build Simple Reflex Container Image
The most basic production deployment exposes two HTTP ports and relies on an
existing load balancer to forward the traffic appropriately.
The main `Dockerfile` is intended to build a very simple, single container deployment that runs
the Reflex frontend and backend together, exposing ports 3000 and 8000.
## `simple-one-port`
To build your container image run the following command:
This deployment exports the frontend statically and serves it via a single HTTP
port using Caddy. This is useful for platforms that only support a single port
or where running a node server in the container is undesirable.
```bash
docker build -t reflex-app:latest .
```
## `production-compose`
## Start Container Service
This deployment is intended for use with a standalone VPS that is only hosting a
single Reflex app. It provides the entire stack in a single `compose.yaml`
including a webserver, one or more backend instances, redis, and a postgres
database.
Finally, you can start your Reflex container service as follows:
## `production-app-platform`
```bash
docker run -it --rm -p 3000:3000 -p 8000:8000 --name app reflex-app:latest
```
It may take a few seconds for the service to become available.
Access your app at http://localhost:3000.
Note that this container has _no persistence_ and will lose all data when
stopped. You can use bind mounts or named volumes to persist the database and
uploaded_files directories as needed.
# Production Service with Docker Compose and Caddy
An example production deployment uses automatic TLS with Caddy serving static files
for the frontend and proxying requests to both the frontend and backend.
Copy the following files to your project directory:
* `compose.yaml`
* `compose.prod.yaml`
* `compose.tools.yaml`
* `prod.Dockerfile`
* `Caddy.Dockerfile`
* `Caddyfile`
The production app container, based on `prod.Dockerfile`, builds and exports the
frontend statically (to be served by Caddy). The resulting image only runs the
backend service.
The `webserver` service, based on `Caddy.Dockerfile`, copies the static frontend
and `Caddyfile` into the container to configure the reverse proxy routes that will
forward requests to the backend service. Caddy will automatically provision TLS
for localhost or the domain specified in the environment variable `DOMAIN`.
This type of deployment should use less memory and be more performant since
nodejs is not required at runtime.
## Customize `Caddyfile` (optional)
If the app uses additional backend API routes, those should be added to the
`@backend_routes` path matcher to ensure they are forwarded to the backend.
## Build Reflex Production Service
During build, set `DOMAIN` environment variable to the domain where the app will
be hosted! (Do not include http or https, it will always use https).
**If `DOMAIN` is not provided, the service will default to `localhost`.**
```bash
DOMAIN=example.com docker compose build
```
This will build both the `app` service from the `prod.Dockerfile` and the `webserver`
service via `Caddy.Dockerfile`.
## Run Reflex Production Service
```bash
DOMAIN=example.com docker compose up
```
The app should be available at the specified domain via HTTPS. Certificate
provisioning will occur automatically and may take a few minutes.
### Data Persistence
Named docker volumes are used to persist the app database (`db-data`),
uploaded_files (`upload-data`), and caddy TLS keys and certificates
(`caddy-data`).
## More Robust Deployment
For a more robust deployment, consider bringing the service up with
`compose.prod.yaml` which includes postgres database and redis cache, allowing
the backend to run with multiple workers and service more requests.
```bash
DOMAIN=example.com docker compose -f compose.yaml -f compose.prod.yaml up -d
```
Postgres uses its own named docker volume for data persistence.
## Admin Tools
When needed, the services in `compose.tools.yaml` can be brought up, providing
graphical database administration (Adminer on http://localhost:8080) and a
redis cache browser (redis-commander on http://localhost:8081). It is not recommended
to deploy these services if they are not in active use.
```bash
DOMAIN=example.com docker compose -f compose.yaml -f compose.prod.yaml -f compose.tools.yaml up -d
```
# Container Hosting
Most container hosting services automatically terminate TLS and expect the app
to be listening on a single port (typically `$PORT`).
To host a Reflex app on one of these platforms, like Google Cloud Run, Render,
Railway, etc, use `app.Dockerfile` to build a single image containing a reverse
proxy that will serve that frontend as static files and proxy requests to the
backend for specific endpoints.
If the chosen platform does not support buildx and thus heredoc, you can copy
the Caddyfile configuration into a separate Caddyfile in the root of the
project.
This example deployment is intended for use with App hosting platforms, like
Azure, AWS, or Google Cloud Run. It is the backend of the deployment, which
depends on a separately hosted redis instance and static frontend deployment.

View File

@ -0,0 +1,5 @@
.web
.git
__pycache__/*
Dockerfile
uploaded_files

View File

@ -0,0 +1,65 @@
# This docker file is intended to be used with container hosting services
#
# After deploying this image, get the URL pointing to the backend service
# and run API_URL=https://path-to-my-container.example.com reflex export frontend
# then copy the contents of `frontend.zip` to your static file server (github pages, s3, etc).
#
# Azure Static Web App example:
# npx @azure/static-web-apps-cli deploy --env production --app-location .web/_static
#
# For dynamic routes to function properly, ensure that 404s are redirected to /404 on the
# static file host (for github pages, this works out of the box; remember to create .nojekyll).
#
# For azure static web apps, add `staticwebapp.config.json` to to `.web/_static` with the following:
# {
# "responseOverrides": {
# "404": {
# "rewrite": "/404.html"
# }
# }
# }
#
# Note: many container hosting platforms require amd64 images, so when building on an M1 Mac
# for example, pass `docker build --platform=linux/amd64 ...`
# Stage 1: init
FROM python:3.13 as init
ARG uv=/root/.local/bin/uv
# Install `uv` for faster package bootstrapping
ADD --chmod=755 https://astral.sh/uv/install.sh /install.sh
RUN /install.sh && rm /install.sh
# Copy local context to `/app` inside container (see .dockerignore)
WORKDIR /app
COPY . .
RUN mkdir -p /app/data /app/uploaded_files
# Create virtualenv which will be copied into final container
ENV VIRTUAL_ENV=/app/.venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
RUN $uv venv
# Install app requirements and reflex inside virtualenv
RUN $uv pip install -r requirements.txt
# Deploy templates and prepare app
RUN reflex init
# Stage 2: copy artifacts into slim image
FROM python:3.13-slim
WORKDIR /app
RUN adduser --disabled-password --home /app reflex
COPY --chown=reflex --from=init /app /app
# Install libpq-dev for psycopg (skip if not using postgres).
RUN apt-get update -y && apt-get install -y libpq-dev && rm -rf /var/lib/apt/lists/*
USER reflex
ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1
# Needed until Reflex properly passes SIGTERM on backend.
STOPSIGNAL SIGKILL
# Always apply migrations before starting the backend.
CMD [ -d alembic ] && reflex db migrate; \
exec reflex run --env prod --backend-only --backend-port ${PORT:-8000}

View File

@ -0,0 +1,113 @@
# production-app-platform
This example deployment is intended for use with App hosting platforms, like
Azure, AWS, or Google Cloud Run.
## Architecture
The production deployment consists of a few pieces:
* Backend container - built by `Dockerfile` Runs the Reflex backend
service on port 8000 and is scalable to multiple instances.
* Redis container - A single instance the standard `redis` docker image should
share private networking with the backend
* Static frontend - HTML/CSS/JS files that are hosted via a CDN or static file
server. This is not included in the docker image.
## Deployment
These general steps do not cover the specifics of each platform, but all platforms should
support the concepts described here.
### Vnet
All containers in the deployment should be hooked up to the same virtual private
network so they can access the redis service and optionally the database server.
The vnet should not be exposed to the internet, use an ingress rule to terminate
TLS at the load balancer and forward the traffic to a backend service replica.
### Redis
Deploy a `redis` instance on the vnet.
### Backend
The backend is built by the `Dockerfile` in this directory. When deploying the
backend, be sure to set REDIS_URL=redis://internal-redis-hostname to connect to
the redis service.
### Ingress
Configure the load balancer for the app to forward traffic to port 8000 on the
backend service replicas. Most platforms will generate an ingress hostname
automatically. Make sure when you access the ingress endpoint on `/ping` that it
returns "pong", indicating that the backend is up an available.
### Frontend
The frontend should be hosted on a static file server or CDN.
**Important**: when exporting the frontend, set the API_URL environment variable
to the ingress hostname of the backend service.
If you will host the frontend from a path other than the root, set the
`FRONTEND_PATH` environment variable appropriately when exporting the frontend.
Most static hosts will automatically use the `/404.html` file to handle 404
errors. _This is essential for dynamic routes to work correctly._ Ensure that
missing routes return the `/404.html` content to the user if this is not the
default behavior.
_For Github Pages_: ensure the file `.nojekyll` is present in the root of the repo
to avoid special processing of underscore-prefix directories, like `_next`.
## Platform Notes
The following sections are currently a work in progress and may be incomplete.
### Azure
In the Azure load balancer, per-message deflate is not supported. Add the following
to your `rxconfig.py` to workaround this issue.
```python
import uvicorn.workers
import reflex as rx
class NoWSPerMessageDeflate(uvicorn.workers.UvicornH11Worker):
CONFIG_KWARGS = {
**uvicorn.workers.UvicornH11Worker.CONFIG_KWARGS,
"ws_per_message_deflate": False,
}
config = rx.Config(
app_name="my_app",
gunicorn_worker_class="rxconfig.NoWSPerMessageDeflate",
)
```
#### Persistent Storage
If you need to use a database or upload files, you cannot save them to the
container volume. Use Azure Files and mount it into the container at /app/uploaded_files.
#### Resource Types
* Create a new vnet with 10.0.0.0/16
* Create a new subnet for redis, database, and containers
* Deploy redis as a Container Instances
* Deploy database server as "Azure Database for PostgreSQL"
* Create a new database for the app
* Set db-url as a secret containing the db user/password connection string
* Deploy Storage account for uploaded files
* Enable access from the vnet and container subnet
* Create a new file share
* In the environment, create a new files share (get the storage key)
* Deploy the backend as a Container App
* Create a custom Container App Environment linked up to the same vnet as the redis container.
* Set REDIS_URL and DB_URL environment variables
* Add the volume from the environment
* Add the volume mount to the container
* Deploy the frontend as a Static Web App

View File

@ -2,11 +2,11 @@
# instance of a Reflex app.
# Stage 1: init
FROM python:3.11 as init
FROM python:3.13 as init
ARG uv=/root/.cargo/bin/uv
ARG uv=/root/.local/bin/uv
# Install `uv` for faster package boostrapping
# Install `uv` for faster package bootstrapping
ADD --chmod=755 https://astral.sh/uv/install.sh /install.sh
RUN /install.sh && rm /install.sh
@ -35,17 +35,18 @@ RUN rm -rf .web && mkdir .web
RUN mv /tmp/_static .web/_static
# Stage 2: copy artifacts into slim image
FROM python:3.11-slim
FROM python:3.13-slim
WORKDIR /app
RUN adduser --disabled-password --home /app reflex
COPY --chown=reflex --from=init /app /app
# Install libpq-dev for psycopg2 (skip if not using postgres).
# Install libpq-dev for psycopg (skip if not using postgres).
RUN apt-get update -y && apt-get install -y libpq-dev && rm -rf /var/lib/apt/lists/*
USER reflex
ENV PATH="/app/.venv/bin:$PATH"
ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1
# Needed until Reflex properly passes SIGTERM on backend.
STOPSIGNAL SIGKILL
# Always apply migrations before starting the backend.
CMD reflex db migrate && reflex run --env prod --backend-only
CMD [ -d alembic ] && reflex db migrate; \
exec reflex run --env prod --backend-only

View File

@ -0,0 +1,75 @@
# production-compose
This example production deployment uses automatic TLS with Caddy serving static
files for the frontend and proxying requests to both the frontend and backend.
It is intended for use with a standalone VPS that is only hosting a single
Reflex app.
The production app container (`Dockerfile`), builds and exports the frontend
statically (to be served by Caddy). The resulting image only runs the backend
service.
The `webserver` service, based on `Caddy.Dockerfile`, copies the static frontend
and `Caddyfile` into the container to configure the reverse proxy routes that will
forward requests to the backend service. Caddy will automatically provision TLS
for localhost or the domain specified in the environment variable `DOMAIN`.
This type of deployment should use less memory and be more performant since
nodejs is not required at runtime.
## Customize `Caddyfile` (optional)
If the app uses additional backend API routes, those should be added to the
`@backend_routes` path matcher to ensure they are forwarded to the backend.
## Build Reflex Production Service
During build, set `DOMAIN` environment variable to the domain where the app will
be hosted! (Do not include http or https, it will always use https).
**If `DOMAIN` is not provided, the service will default to `localhost`.**
```bash
DOMAIN=example.com docker compose build
```
This will build both the `app` service from the `prod.Dockerfile` and the `webserver`
service via `Caddy.Dockerfile`.
## Run Reflex Production Service
```bash
DOMAIN=example.com docker compose up
```
The app should be available at the specified domain via HTTPS. Certificate
provisioning will occur automatically and may take a few minutes.
### Data Persistence
Named docker volumes are used to persist the app database (`db-data`),
uploaded_files (`upload-data`), and caddy TLS keys and certificates
(`caddy-data`).
## More Robust Deployment
For a more robust deployment, consider bringing the service up with
`compose.prod.yaml` which includes postgres database and redis cache, allowing
the backend to run with multiple workers and service more requests.
```bash
DOMAIN=example.com docker compose -f compose.yaml -f compose.prod.yaml up -d
```
Postgres uses its own named docker volume for data persistence.
## Admin Tools
When needed, the services in `compose.tools.yaml` can be brought up, providing
graphical database administration (Adminer on http://localhost:8080) and a
redis cache browser (redis-commander on http://localhost:8081). It is not recommended
to deploy these services if they are not in active use.
```bash
DOMAIN=example.com docker compose -f compose.yaml -f compose.prod.yaml -f compose.tools.yaml up -d
```

View File

@ -15,7 +15,7 @@ services:
app:
environment:
DB_URL: postgresql+psycopg2://postgres:secret@db/postgres
DB_URL: postgresql+psycopg://postgres:secret@db/postgres
REDIS_URL: redis://redis:6379
depends_on:
- db

View File

@ -12,7 +12,6 @@ services:
DB_URL: sqlite:///data/reflex.db
build:
context: .
dockerfile: prod.Dockerfile
volumes:
- db-data:/app/data
- upload-data:/app/uploaded_files

View File

@ -0,0 +1,3 @@
.web
!.web/bun.lockb
!.web/package.json

View File

@ -0,0 +1,14 @@
:{$PORT}
encode gzip
@backend_routes path /_event/* /ping /_upload /_upload/*
handle @backend_routes {
reverse_proxy localhost:8000
}
root * /srv
route {
try_files {path} {path}/ /404.html
file_server
}

View File

@ -0,0 +1,62 @@
# This Dockerfile is used to deploy a single-container Reflex app instance
# to services like Render, Railway, Heroku, GCP, and others.
# If the service expects a different port, provide it here (f.e Render expects port 10000)
ARG PORT=8080
# Only set for local/direct access. When TLS is used, the API_URL is assumed to be the same as the frontend.
ARG API_URL
# It uses a reverse proxy to serve the frontend statically and proxy to backend
# from a single exposed port, expecting TLS termination to be handled at the
# edge by the given platform.
FROM python:3.13 as builder
RUN mkdir -p /app/.web
RUN python -m venv /app/.venv
ENV PATH="/app/.venv/bin:$PATH"
WORKDIR /app
# Install python app requirements and reflex in the container
COPY requirements.txt .
RUN pip install -r requirements.txt
# Install reflex helper utilities like bun/fnm/node
COPY rxconfig.py ./
RUN reflex init
# Install pre-cached frontend dependencies (if exist)
COPY *.web/bun.lockb *.web/package.json .web/
RUN if [ -f .web/bun.lockb ]; then cd .web && ~/.local/share/reflex/bun/bin/bun install --frozen-lockfile; fi
# Copy local context to `/app` inside container (see .dockerignore)
COPY . .
ARG PORT API_URL
# Download other npm dependencies and compile frontend
RUN API_URL=${API_URL:-http://localhost:$PORT} reflex export --loglevel debug --frontend-only --no-zip && mv .web/_static/* /srv/ && rm -rf .web
# Final image with only necessary files
FROM python:3.13-slim
# Install Caddy and redis server inside image
RUN apt-get update -y && apt-get install -y caddy redis-server && rm -rf /var/lib/apt/lists/*
ARG PORT API_URL
ENV PATH="/app/.venv/bin:$PATH" PORT=$PORT API_URL=${API_URL:-http://localhost:$PORT} REDIS_URL=redis://localhost PYTHONUNBUFFERED=1
WORKDIR /app
COPY --from=builder /app /app
COPY --from=builder /srv /srv
# Needed until Reflex properly passes SIGTERM on backend.
STOPSIGNAL SIGKILL
EXPOSE $PORT
# Apply migrations before starting the backend.
CMD [ -d alembic ] && reflex db migrate; \
caddy start && \
redis-server --daemonize yes && \
exec reflex run --env prod --backend-only

View File

@ -0,0 +1,37 @@
# production-one-port
This docker deployment runs Reflex in prod mode, exposing a single HTTP port:
* `8080` (`$PORT`) - Caddy server hosting the frontend statically and proxying requests to the backend.
The deployment also runs a local Redis server to store state for each user.
Conceptually it is similar to the `simple-one-port` example except it:
* has layer caching for python, reflex, and node dependencies
* uses multi-stage build to reduce the size of the final image
Using this method may be preferable for deploying in memory constrained
environments, because it serves a static frontend export, rather than running
the NextJS server via node.
## Build
```console
docker build -t reflex-production-one-port .
```
## Run
```console
docker run -p 8080:8080 reflex-production-one-port
```
Note that this container has _no persistence_ and will lose all data when
stopped. You can use bind mounts or named volumes to persist the database and
uploaded_files directories as needed.
## Usage
This container should be used with an existing load balancer or reverse proxy to
terminate TLS.
It is also useful for deploying to simple app platforms, such as Render or Heroku.

View File

@ -1 +0,0 @@
reflex

View File

@ -0,0 +1,5 @@
.web
.git
__pycache__/*
Dockerfile
uploaded_files

View File

@ -0,0 +1,14 @@
:{$PORT}
encode gzip
@backend_routes path /_event/* /ping /_upload /_upload/*
handle @backend_routes {
reverse_proxy localhost:8000
}
root * /srv
route {
try_files {path} {path}/ /404.html
file_server
}

View File

@ -4,37 +4,19 @@
# It uses a reverse proxy to serve the frontend statically and proxy to backend
# from a single exposed port, expecting TLS termination to be handled at the
# edge by the given platform.
FROM python:3.11
FROM python:3.13
# If the service expects a different port, provide it here (f.e Render expects port 10000)
ARG PORT=8080
# Only set for local/direct access. When TLS is used, the API_URL is assumed to be the same as the frontend.
ARG API_URL
ENV PORT=$PORT API_URL=${API_URL:-http://localhost:$PORT}
ENV PORT=$PORT API_URL=${API_URL:-http://localhost:$PORT} REDIS_URL=redis://localhost PYTHONUNBUFFERED=1
# Install Caddy server inside image
RUN apt-get update -y && apt-get install -y caddy && rm -rf /var/lib/apt/lists/*
# Install Caddy and redis server inside image
RUN apt-get update -y && apt-get install -y caddy redis-server && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Create a simple Caddyfile to serve as reverse proxy
RUN cat > Caddyfile <<EOF
:{\$PORT}
encode gzip
@backend_routes path /_event/* /ping /_upload /_upload/*
handle @backend_routes {
reverse_proxy localhost:8000
}
root * /srv
route {
try_files {path} {path}/ /404.html
file_server
}
EOF
# Copy local context to `/app` inside container (see .dockerignore)
COPY . .
@ -54,4 +36,6 @@ EXPOSE $PORT
# Apply migrations before starting the backend.
CMD [ -d alembic ] && reflex db migrate; \
caddy start && reflex run --env prod --backend-only --loglevel debug
caddy start && \
redis-server --daemonize yes && \
exec reflex run --env prod --backend-only

View File

@ -0,0 +1,36 @@
# simple-one-port
This docker deployment runs Reflex in prod mode, exposing a single HTTP port:
* `8080` (`$PORT`) - Caddy server hosting the frontend statically and proxying requests to the backend.
The deployment also runs a local Redis server to store state for each user.
Using this method may be preferable for deploying in memory constrained
environments, because it serves a static frontend export, rather than running
the NextJS server via node.
For platforms which only terminate TLS to a single port, this container can be
deployed instead of the `simple-two-port` example.
## Build
```console
docker build -t reflex-simple-one-port .
```
## Run
```console
docker run -p 8080:8080 reflex-simple-one-port
```
Note that this container has _no persistence_ and will lose all data when
stopped. You can use bind mounts or named volumes to persist the database and
uploaded_files directories as needed.
## Usage
This container should be used with an existing load balancer or reverse proxy to
terminate TLS.
It is also useful for deploying to simple app platforms, such as Render or Heroku.

View File

@ -0,0 +1,5 @@
.web
.git
__pycache__/*
Dockerfile
uploaded_files

View File

@ -1,5 +1,8 @@
# This Dockerfile is used to deploy a simple single-container Reflex app instance.
FROM python:3.11
FROM python:3.13
RUN apt-get update && apt-get install -y redis-server && rm -rf /var/lib/apt/lists/*
ENV REDIS_URL=redis://localhost PYTHONUNBUFFERED=1
# Copy local context to `/app` inside container (see .dockerignore)
WORKDIR /app
@ -18,4 +21,6 @@ RUN reflex export --frontend-only --no-zip
STOPSIGNAL SIGKILL
# Always apply migrations before starting the backend.
CMD [ -d alembic ] && reflex db migrate; reflex run --env prod
CMD [ -d alembic ] && reflex db migrate; \
redis-server --daemonize yes && \
exec reflex run --env prod

View File

@ -0,0 +1,44 @@
# simple-two-port
This docker deployment runs Reflex in prod mode, exposing two HTTP ports:
* `3000` - node NextJS server using optimized production build
* `8000` - python gunicorn server hosting the Reflex backend
The deployment also runs a local Redis server to store state for each user.
## Build
```console
docker build -t reflex-simple-two-port .
```
## Run
```console
docker run -p 3000:3000 -p 8000:8000 reflex-simple-two-port
```
Note that this container has _no persistence_ and will lose all data when
stopped. You can use bind mounts or named volumes to persist the database and
uploaded_files directories as needed.
## Usage
This container should be used with an existing load balancer or reverse proxy to
route traffic to the appropriate port inside the container.
For example, the following Caddyfile can be used to terminate TLS and forward
traffic to the frontend and backend from outside the container.
```
my-domain.com
encode gzip
@backend_routes path /_event/* /ping /_upload /_upload/*
handle @backend_routes {
reverse_proxy localhost:8000
}
reverse_proxy localhost:3000
```

261
docs/de/README.md Normal file
View File

@ -0,0 +1,261 @@
```diff
+ Suchst du nach Pynecone? Dann bist du hier in der richtigen Repository. Pynecone wurde in Reflex umbenannt. +
```
<div align="center">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_dark.svg#gh-light-mode-only" alt="Reflex Logo" width="300px">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_light.svg#gh-dark-mode-only" alt="Reflex Logo" width="300px">
<hr>
### **✨ Performante, anpassbare Web-Apps in purem Python. Bereitstellung in Sekunden. ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentation](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
# Reflex
Reflex ist eine Bibliothek, mit der man Full-Stack-Web-Applikationen in purem Python erstellen kann.
Wesentliche Merkmale:
* **Pures Python** - Schreibe dein Front- und Backend in Python, es gibt also keinen Grund, JavaScript zu lernen.
* **Volle Flexibilität** - Reflex ist einfach zu handhaben, kann aber auch für komplexe Anwendungen skaliert werden.
* **Sofortige Bereitstellung** - Nach dem Erstellen kannst du deine App mit einem [einzigen Befehl](https://reflex.dev/docs/hosting/deploy-quick-start/) bereitstellen oder auf deinem eigenen Server hosten.
Auf unserer [Architektur-Seite](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture) erfahren Sie, wie Reflex unter der Haube funktioniert.
## ⚙️ Installation
Öffne ein Terminal und führe den folgenden Befehl aus (benötigt Python 3.10+):
```bash
pip install reflex
```
## 🥳 Erstelle deine erste App
Die Installation von `reflex` installiert auch das `reflex`-Kommandozeilen-Tool.
Teste, ob die Installation erfolgreich war, indem du ein neues Projekt erstellst. (Ersetze `my_app_name` durch deinen Projektnamen):
```bash
mkdir my_app_name
cd my_app_name
reflex init
```
Dieser Befehl initialisiert eine Vorlage in deinem neuen Verzeichnis.
Du kannst diese App im Entwicklungsmodus ausführen:
```bash
reflex run
```
Du solltest deine App unter http://localhost:3000 laufen sehen.
Nun kannst du den Quellcode in `my_app_name/my_app_name.py` ändern. Reflex hat schnelle Aktualisierungen, sodass du deine Änderungen sofort siehst, wenn du deinen Code speicherst.
## 🫧 Beispiel-App
Lass uns ein Beispiel durchgehen: die Erstellung einer Benutzeroberfläche für die Bildgenerierung mit [DALL·E](https://platform.openai.com/docs/guides/images/image-generation?context=node). Zur Vereinfachung rufen wir einfach die [OpenAI-API](https://platform.openai.com/docs/api-reference/authentication) auf, aber du könntest dies auch durch ein lokal ausgeführtes ML-Modell ersetzen.
&nbsp;
<div align="center">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/dalle.gif" alt="Eine Benutzeroberfläche für DALL·E, die im Prozess der Bildgenerierung gezeigt wird." width="550" />
</div>
&nbsp;
Hier ist der komplette Code, um dies zu erstellen. Das alles wird in einer Python-Datei gemacht!
```python
import reflex as rx
import openai
openai_client = openai.OpenAI()
class State(rx.State):
"""Der Zustand der App."""
prompt = ""
image_url = ""
processing = False
complete = False
def get_image(self):
"""Hole das Bild aus dem 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",
)
# Füge Zustand und Seite zur App hinzu.
app = rx.App()
app.add_page(index, title="Reflex:DALL-E")
```
## Schauen wir uns das mal genauer an.
<div align="center">
<img src="docs/images/dalle_colored_code_example.png" alt="Erläuterung der Unterschiede zwischen Backend- und Frontend-Teilen der DALL-E-App." width="900" />
</div>
### **Reflex-UI**
Fangen wir mit der Benutzeroberfläche an.
```python
def index():
return rx.center(
...
)
```
Diese `index`-Funktion definiert das Frontend der App.
Wir verwenden verschiedene Komponenten wie `center`, `vstack`, `input` und `button`, um das Frontend zu erstellen. Komponenten können ineinander verschachtelt werden, um komplexe Layouts zu erstellen. Und du kannst Schlüsselwortargumente verwenden, um sie mit der vollen Kraft von CSS zu stylen.
Reflex wird mit [über 60 eingebauten Komponenten](https://reflex.dev/docs/library) geliefert, die dir den Einstieg erleichtern. Wir fügen aktiv weitere Komponenten hinzu, und es ist einfach, [eigene Komponenten zu erstellen](https://reflex.dev/docs/wrapping-react/overview/).
### **State**
Reflex stellt deine Benutzeroberfläche als Funktion deines Zustands dar.
```python
class State(rx.State):
"""Der Zustand der App."""
prompt = ""
image_url = ""
processing = False
complete = False
```
Der Zustand definiert alle Variablen (genannt Vars) in einer App, die sich ändern können, und die Funktionen, die sie ändern.
Hier besteht der Zustand aus einem `prompt` und einer `image_url`. Es gibt auch die Booleans `processing` und `complete`, um anzuzeigen, wann der Button deaktiviert werden soll (während der Bildgenerierung) und wann das resultierende Bild angezeigt werden soll.
### **Event-Handler**
```python
def get_image(self):
"""Hole das Bild aus dem 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
```
Innerhalb des Zustands definieren wir Funktionen, die als Event-Handler bezeichnet werden und die Zustand-Variablen ändern. Event-Handler sind die Art und Weise, wie wir den Zustand in Reflex ändern können. Sie können als Reaktion auf Benutzeraktionen aufgerufen werden, z.B. beim Klicken auf eine Schaltfläche oder bei der Eingabe in ein Textfeld. Diese Aktionen werden als Ereignisse bezeichnet.
Unsere DALL-E.-App hat einen Event-Handler, `get_image`, der dieses Bild von der OpenAI-API abruft. Die Verwendung von `yield` in der Mitte eines Event-Handlers führt zu einer Aktualisierung der Benutzeroberfläche. Andernfalls wird die Benutzeroberfläche am Ende des Ereignishandlers aktualisiert.
### **Routing**
Schließlich definieren wir unsere App.
```python
app = rx.App()
```
Wir fügen der Indexkomponente eine Seite aus dem Stammverzeichnis der Anwendung hinzu. Wir fügen auch einen Titel hinzu, der in der Seitenvorschau/Browser-Registerkarte angezeigt wird.
```python
app.add_page(index, title="DALL-E")
```
Du kannst eine mehrseitige App erstellen, indem du weitere Seiten hinzufügst.
## 📑 Ressourcen
<div align="center">
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Komponentenbibliothek](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Galerie](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [Bereitstellung](https://reflex.dev/docs/hosting/deploy-quick-start) &nbsp;
</div>
## ✅ Status
Reflex wurde im Dezember 2022 unter dem Namen Pynecone gestartet.
Ab Februar 2024 befindet sich unser Hosting-Service in der Alpha-Phase! In dieser Zeit kann jeder seine Apps kostenlos bereitstellen. Siehe unsere [Roadmap](https://github.com/reflex-dev/reflex/issues/2727), um zu sehen, was geplant ist.
Reflex hat wöchentliche Veröffentlichungen und neue Features! Stelle sicher, dass du dieses Repository mit einem :star: Stern markierst und :eyes: beobachtest, um auf dem Laufenden zu bleiben.
## Beitragende
Wir begrüßen Beiträge jeder Größe! Hier sind einige gute Möglichkeiten, um in der Reflex-Community zu starten.
- **Tritt unserem Discord bei**: Unser [Discord](https://discord.gg/T5WSbC2YtQ) ist der beste Ort, um Hilfe für dein Reflex-Projekt zu bekommen und zu besprechen, wie du beitragen kannst.
- **GitHub-Diskussionen**: Eine großartige Möglichkeit, über Funktionen zu sprechen, die du hinzugefügt haben möchtest oder Dinge, die verwirrend sind/geklärt werden müssen.
- **GitHub-Issues**: [Issues](https://github.com/reflex-dev/reflex/issues) sind eine ausgezeichnete Möglichkeit, Bugs zu melden. Außerdem kannst du versuchen, ein bestehendes Problem zu lösen und eine PR einzureichen.
Wir suchen aktiv nach Mitwirkenden, unabhängig von deinem Erfahrungslevel oder deiner Erfahrung. Um beizutragen, sieh dir [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md) an.
## Vielen Dank an unsere Mitwirkenden:
<a href="https://github.com/reflex-dev/reflex/graphs/contributors">
<img src="https://contrib.rocks/image?repo=reflex-dev/reflex" />
</a>
## Lizenz
Reflex ist Open-Source und lizenziert unter der [Apache License 2.0](LICENSE).

View File

@ -1,5 +1,5 @@
```diff
+ ¿Buscando Pynecone? Estas en el repositorio correcto. Pynecone ha sido renomabrado a Reflex. +
+ ¿Buscando Pynecone? Estás en el repositorio correcto. Pynecone ha sido renombrado a Reflex. +
```
<div align="center">
@ -8,28 +8,42 @@
<hr>
### **✨ Aplicaciones web personalizables y eficaces en Python puro. Despliega tú aplicación en segundos. ✨**
### **✨ Aplicaciones web personalizables y eficaces en Python puro. Despliega tu aplicación en segundos. ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![tests](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentaiton](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
![Pruebas](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![Versiones](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentación](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md)
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
# Reflex
Reflex es una biblioteca para construir aplicaciones web full-stack en Python puro.
Características clave:
* **Python puro** - Escribe el frontend y backend de tu aplicación en Python, sin necesidad de aprender JavaScript.
* **Flexibilidad total** - Reflex es fácil para empezar, pero también puede escalar a aplicaciones complejas.
* **Despliegue instantáneo** - Después de construir, despliega tu aplicación con un [solo comando](https://reflex.dev/docs/hosting/deploy-quick-start/) u hospédala en tu propio servidor.
Consulta nuestra [página de arquitectura](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture) para aprender cómo funciona Reflex en detalle.
## ⚙️ Instalación
Abra un terminal y ejecute (Requiere Python 3.7+):
Abra un terminal y ejecute (Requiere Python 3.10+):
```bash
pip install reflex
```
## 🥳 Crea tú primera aplicación
## 🥳 Crea tu primera aplicación
Al instalar `reflex` tambien se instala la herramienta de línea de comandos `reflex`.
Al instalar `reflex` también se instala la herramienta de línea de comandos `reflex`.
Compruebe que la instalación se ha realizado correctamente creando un nuevo proyecto. (Sustituye `my_app_name` por el nombre de tu proyecto):
@ -39,7 +53,7 @@ cd my_app_name
reflex init
```
Este comando inicializa una aplicación de ejemplo (plantilla) en tu nuevo directorio.
Este comando inicializa una plantilla en tu nuevo directorio.
Puedes iniciar esta aplicación en modo de desarrollo:
@ -54,12 +68,12 @@ Ahora puede modificar el código fuente en `my_app_name/my_app_name.py`. Reflex
## 🫧 Ejemplo de una Aplicación
Veamos un ejemplo: crearemos una UI de generación de imágenes en torno a DALL-E. Para simplificar, solo llamamos a la API de OpenAI, pero podrías reeemplazar esto con un modelo ML ejecutado localmente.
Veamos un ejemplo: crearemos una UI de generación de imágenes en torno a [DALL·E](https://platform.openai.com/docs/guides/images/image-generation?context=node). Para simplificar, solo llamamos a la [API de OpenAI](https://platform.openai.com/docs/api-reference/authentication), pero podrías reemplazar esto con un modelo ML ejecutado localmente.
&nbsp;
<div align="center">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/dalle.gif" alt="A frontend wrapper for DALL·E, shown in the process of generating an image." width="550" />
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/dalle.gif" alt="Un envoltorio frontend para DALL·E, mostrado en el proceso de generar una imagen." width="550" />
</div>
&nbsp;
@ -70,61 +84,65 @@ Aquí está el código completo para crear esto. ¡Todo esto se hace en un archi
import reflex as rx
import openai
openai.api_key = "YOUR_API_KEY"
openai_client = openai.OpenAI()
class State(rx.State):
"""The app state."""
"""El estado de la aplicación"""
prompt = ""
image_url = ""
processing = False
complete = False
def get_image(self):
"""Get the image from the prompt."""
"""Obtiene la imagen desde la consulta."""
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"]
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"),
rx.input(placeholder="Enter a prompt", on_blur=State.set_prompt),
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",
"Generate Image",
on_click=State.get_image,
is_loading=State.processing,
width="100%",
width="25em",
loading=State.processing
),
rx.cond(
State.complete,
rx.image(
src=State.image_url,
height="25em",
width="25em",
)
rx.image(src=State.image_url, width="20em"),
),
padding="2em",
shadow="lg",
border_radius="lg",
align="center",
),
width="100%",
height="100vh",
)
# Add state and page to the app.
# Agrega el estado y la pagina a la aplicación
app = rx.App()
app.add_page(index, title="reflex:DALL·E")
app.add_page(index, title="Reflex:DALL-E")
```
## Vamos a analizarlo.
<div align="center">
<img src="https://github.com/reflex-dev/reflex/blob/main/docs/images/dalle_colored_code_example.png?raw=true" alt="Explicando las diferencias entre las partes del backend y frontend de la aplicación DALL-E." width="900" />
</div>
### **Reflex UI**
Empezemos por la interfaz de usuario (UI).
@ -138,17 +156,17 @@ def index():
Esta función `index` define el frontend de la aplicación.
Utilizamos diferentes componentes como `center`, `vstack`, `input`, y `button` para construir el frontend. Los componentes pueden anidarse unos dentro de otros para crear diseños complejos. Además, puedes usar argumentos (keyword args) para darles estilo con toda la potencia de CSS.
Utilizamos diferentes componentes como `center`, `vstack`, `input`, y `button` para construir el frontend. Los componentes pueden anidarse unos dentro de otros para crear diseños complejos. Además, puedes usar argumentos de tipo keyword para darles estilo con toda la potencia de CSS.
Reflex viene con [mas de 60+ componentes incorporados](https://reflex.dev/docs/library) para ayudarle a empezar. Estamos añadiendo activamente más componentes y es fácil [crear sus propios componentes](https://reflex.dev/docs/advanced-guide/wrapping-react).
Reflex viene con [mas de 60 componentes incorporados](https://reflex.dev/docs/library) para ayudarle a empezar. Estamos añadiendo activamente más componentes y es fácil [crear sus propios componentes](https://reflex.dev/docs/wrapping-react/overview/).
### **State**
### **Estado**
Reflex representa su UI en función de su estado (State).
Reflex representa su UI como una función de su estado (State).
```python
class State(rx.State):
"""The app state."""
"""El estado de la aplicación"""
prompt = ""
image_url = ""
processing = False
@ -157,28 +175,30 @@ class State(rx.State):
El estado (State) define todas las variables (llamadas vars) de una aplicación que pueden cambiar y las funciones que las modifican.
Aquí el estado (State) se compone de `prompt` e `image_url`. También están los booleanos `processing` y `complete` para poder indicar cuándo mostrar el progreso circular y la imagen.
Aquí el estado se compone de `prompt` e `image_url`. También están los booleanos `processing` y `complete` para indicar cuando se deshabilite el botón (durante la generación de la imagen) y cuando se muestre la imagen resultante.
### **Event Handlers**
### **Manejadores de Evento**
```python
def get_image(self):
"""Get the image from the prompt."""
"""Obtiene la imagen desde la consulta."""
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"]
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
```
Dentro del estado (State), definimos funciones llamadas "event handlers" que cambian los 'state vars'. Event handlers, son la manera que podemos modificar el 'state' en Reflex. Pueden ser activados en respuesta a las acciones del usuario, como hacer clic en un botón o escribir en un cuadro de texto. Estas acciones se llaman eventos 'events'.
Dentro del estado, definimos funciones llamadas manejadores de eventos que cambian las variables de estado. Los Manejadores de Evento son la manera que podemos modificar el estado en Reflex. Pueden ser activados en respuesta a las acciones del usuario, como hacer clic en un botón o escribir en un cuadro de texto. Estas acciones se llaman eventos.
Nuestra aplicación DALL·E. tiene un controlador de eventos "event handler", `get_image` que recibe esta imagen del OpenAI API. El uso de `yield` en medio de un controlador de eventos "event handler" hará que la UI se actualice. De lo contrario, la interfaz se actualizará al final del controlador de eventos "event handler".
Nuestra aplicación DALL·E tiene un manipulador de eventos, `get_image` que recibe esta imagen del OpenAI API. El uso de `yield` en medio de un manipulador de eventos hará que la UI se actualice. De lo contrario, la interfaz se actualizará al final del manejador de eventos.
### **Routing**
### **Enrutamiento**
Por último, definimos nuestra app.
@ -198,36 +218,28 @@ Puedes crear una aplicación multipágina añadiendo más páginas.
<div align="center">
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Biblioteca de Componentes](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Galería](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [Hospedaje](https://reflex.dev/docs/hosting/deploy) &nbsp;
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Librería de componentes](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Galería](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [Despliegue](https://reflex.dev/docs/hosting/deploy-quick-start) &nbsp;
</div>
## ✅ Estado
Reflex se lanzó en diciembre de 2022 con el nombre de Pynecone.
¡Desde febrero de 2024, nuestro servicio de alojamiento está en fase alfa! Durante este tiempo, cualquiera puede implementar sus aplicaciones de forma gratuita. Consulta nuestra [hoja de ruta](https://github.com/reflex-dev/reflex/issues/2727) para ver qué está planeado.
## ✅ Estatus
¡Reflex tiene nuevas versiones y características cada semana! Asegúrate de :star: marcar como favorito y :eyes: seguir este repositorio para mantenerte actualizado.
Reflex se lanzó en Diciembre de 2022 con el nombre Pynecone.
A partir de julio de 2023, nos encontramos en la etapa de **Beta Pública**.
- :white_check_mark: **Alpha Pública**: Cualquier persona puede instalar y usar Reflex. Puede haber problemas, pero estamos trabajando activamente para resolverlos.
- :large_orange_diamond: **Beta Pública**: Suficientemente estable para casos de uso no empresariales.
- **Beta de Hospedaje Público**: ¡_Opcionalmente_, despliega y hospeda tus aplicaciónes en Reflex!
- **Público**: Reflex está listo para producción.
¡Reflex tiene nuevas versiones y características que se lanzan cada semana! Aseguraté de darnos una :star: estrella y :eyes: revisa este repositorio para mantenerte actualizado.
## Contribuyendo
## Contribuciones
¡Aceptamos contribuciones de cualquier tamaño! A continuación encontrará algunas buenas formas de iniciarse en la comunidad Reflex.
- **Únete a nuestro Discord**: Nuestro [Discord](https://discord.gg/T5WSbC2YtQ) es el mejor lugar para obtener ayuda en su proyecto Reflex y discutir cómo puedes contribuir.
- **Discusiones de GitHub**: Una excelente manera de hablar sobre las características que deseas agregar o las cosas que te resusltan confusas o necesitan aclaración.
- **GitHub Issues**: Las incidencias son una forma excelente de informar de errores. Además, puedes intentar resolver un problema exixtente y enviar un PR.
- **Discusiones de GitHub**: Una excelente manera de hablar sobre las características que deseas agregar o las cosas que te resultan confusas o necesitan aclaración.
- **GitHub Issues**: Las incidencias son una forma excelente de informar de errores. Además, puedes intentar resolver un problema existente y enviar un PR.
Buscamos colaboradores, sin importar su nivel o experiencia.
Buscamos colaboradores, sin importar su nivel o experiencia. Para contribuir consulta [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
## Licencia

Binary file not shown.

Before

Width:  |  Height:  |  Size: 455 KiB

After

Width:  |  Height:  |  Size: 370 KiB

View File

@ -1,37 +1,51 @@
```diff
Pynecone की तलाश हैं? आप सही रेपो में हैं। Pynecone का नाम Reflex में बदल दिया गया है। + +
```
<div align="center">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_dark.svg#gh-light-mode-only" alt="Reflex Logo" width="300px">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_light.svg#gh-dark-mode-only" alt="Reflex Logo" width="300px">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_dark.svg#gh-light-mode-only" alt="Reflex लोगो" width="300px">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_light.svg#gh-dark-mode-only" alt="Reflex लोगो" width="300px">
<hr>
### **✨ Python (पायथन) में परफॉर्मेंट, अनुकूलनयोग्य वेब ऐप्स। कुछ सेकंड्स में ही डिप्लॉय करें ✨**
### **✨ प्रदर्शनकारी, अनुकूलित वेब ऐप्स, शुद्ध Python में। सेकंडों में तैनात करें। ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![tests](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentaiton](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md)
---
## ⚙️ इंस्टॉलेशन
## [English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
एक टर्मिनल खोलें और चलाएं (Python 3.8+ की आवश्यकता है):
# Reflex
Reflex शुद्ध पायथन में पूर्ण-स्टैक वेब ऐप्स बनाने के लिए एक लाइब्रेरी है।
मुख्य विशेषताएँ:
- **शुद्ध पायथन** - अपने ऐप के फ्रंटएंड और बैकएंड को पायथन में लिखें, जावास्क्रिप्ट सीखने की जरूरत नहीं है।
- **पूर्ण लचीलापन** - Reflex के साथ शुरुआत करना आसान है, लेकिन यह जटिल ऐप्स के लिए भी स्केल कर सकता है।
- **तुरंत तैनाती** - बिल्डिंग के बाद, अपने ऐप को [एकल कमांड](https://reflex.dev/docs/hosting/deploy-quick-start/) के साथ तैनात करें या इसे अपने सर्वर पर होस्ट करें।
Reflex के अंदर के कामकाज को जानने के लिए हमारे [आर्किटेक्चर पेज](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture) को देखें।
## ⚙️ इंस्टॉलेशन (Installation)
एक टर्मिनल खोलें और चलाएं (Python 3.10+ की आवश्यकता है):
```bash
pip install reflex
```
## 🥳 अपना पहला ऐप बनाएं
## 🥳 अपना पहला ऐप बनाएं (Create your first App)
reflex को इंस्टॉल करने से ही reflex कमांड लाइन टूल भी इंस्टॉल हो जाता है।
सुनिश्चित करें कि इंस्टॉलेशन सफल थी, एक नया प्रोजेक्ट बनाकर इसे टेस्ट करें। ('my_app_name' की जगह अपने प्रोजेक्ट का नाम रखें):
सुनिश्चित करें कि इंस्टॉलेशन सफल थी, एक नया प्रोजेक्ट बनाकर इसे टेस्ट करें। ('my_app_name' की जगह अपने प्रोजेक्ट का नाम रखें):
```bash
mkdir my_app_name
@ -51,14 +65,14 @@ reflex run
अब आप my_app_name/my_app_name.py में source कोड को संशोधित कर सकते हैं। Reflex में तेज रिफ्रेश की सुविधा है, इसलिए जब आप अपनी कोड को सहेजते हैं, तो आप अपने बदलावों को तुरंत देख सकते हैं।
## 🫧 उदाहरण ऐप
## 🫧 उदाहरण ऐप (Example App)
एक उदाहरण पर चलते हैं: DALL·E से एक इमेज उत्पन्न करने के लिए UI। सरलता के लिए, हम सिर्फ OpenAI API को बुलाते हैं, लेकिन आप इसे ML मॉडल से बदल सकते हैं locally।
&nbsp;
<div align="center">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/dalle.gif" alt="A frontend wrapper for DALL·E, shown in the process of generating an image." width="550" />
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/dalle.gif" alt="DALL·E के लिए एक फ्रंटएंड रैपर, छवि उत्पन्न करने की प्रक्रिया में दिखाया गया।" width="550" />
</div>
&nbsp;
@ -69,10 +83,12 @@ reflex run
import reflex as rx
import openai
openai.api_key = "YOUR_API_KEY"
openai_client = openai.OpenAI()
class State(rx.State):
"""The app state."""
prompt = ""
image_url = ""
processing = False
@ -85,33 +101,33 @@ class State(rx.State):
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"]
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"),
rx.input(placeholder="Enter a prompt", on_blur=State.set_prompt),
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,
is_loading=State.processing,
width="100%",
width="25em",
loading=State.processing
),
rx.cond(
State.complete,
rx.image(
src=State.image_url,
height="25em",
width="25em",
)
rx.image(src=State.image_url, width="20em"),
),
padding="2em",
shadow="lg",
border_radius="lg",
align="center",
),
width="100%",
height="100vh",
@ -119,10 +135,14 @@ def index():
# Add state and page to the app.
app = rx.App()
app.add_page(index, title="reflex:DALL·E")
app.add_page(index, title="Reflex:DALL-E")
```
## चलो इसे विस्तार से देखते हैं।
## इसे समझते हैं।
<div align="center">
<img src="https://github.com/reflex-dev/reflex/blob/main/docs/images/dalle_colored_code_example.png?raw=true" alt="DALL-E ऐप के बैकएंड और फ्रंटएंड भागों के बीच के अंतर की व्याख्या करता है।" width="900" />
</div>
### **Reflex UI**
@ -156,7 +176,7 @@ class State(rx.State):
स्टेट (state) ऐप में उन सभी वेरिएबल्स (vars) को परिभाषित करती है जो बदल सकती हैं और उन फ़ंक्शनों को जो उन्हें बदलते हैं।
यहां स्टेट (state) में `prompt` और `image_url` शामिल हैं। प्रगति और छवि दिखाने के लिए `processing` और `complete` बूलियन भी हैं।
यहां स्टेट (state) में `prompt` और `image_url` शामिल हैं। प्रगति और छवि दिखाने के लिए `processing` और `complete` बूलियन भी हैं।
### **इवेंट हैंडलर (Event Handlers)**
@ -168,8 +188,10 @@ def get_image(self):
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"]
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
```
@ -197,33 +219,34 @@ app.add_page(index, title="DALL-E")
<div align="center">
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Gallery](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy) &nbsp;
📑 [दस्तावेज़](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [ब्लॉग](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [कॉम्पोनेंट लाइब्रेरी](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [गैलरी](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [तैनाती](https://reflex.dev/docs/hosting/deploy) &nbsp;
</div>
## ✅ स्टेटस (Status)
रिफ्लेक्स को दिसंबर 2022 में पाइनकोन नाम से लॉन्च किया गया
Reflex दिसंबर 2022 में Pynecone नाम से शुरू हुआ
जुलाई 2023 तक, हम **Public Beta** (सार्वजनिक बीटा) चरण में हैं
फरवरी 2024 तक, हमारी होस्टिंग सेवा अल्फा में है! इस समय कोई भी अपने ऐप्स को मुफ्त में तैनात कर सकता है। देखें हमारी [रोडमैप](https://github.com/reflex-dev/reflex/issues/2727) योजनाबद्ध चीज़ों को जानने के लिए
- :white_check_mark: **Public Alpha** (सार्वजनिक अल्फा): कोई भी रिफ्लेक्स इंस्टॉल और उपयोग कर सकता है। कुछ इशू हो सकते हैं, लेकिन हम उन्हें सुलझाने के लिए सक्रिय रूप से काम कर रहे हैं।
- :large_orange_diamond: **Public Beta** (सार्वजनिक बीटा): गैर-उद्यम उपयोग-मामलों के लिए स्थिर।
- **Public Hosting Beta** (सार्वजनिक होस्टिंग बीटा): _Optionally_, अपने ऐप्स को रिफ्लेक्स पर डिप्लॉइ और होस्ट करें!
- **Public** (सार्वजनिक): रिफ्लेक्स उत्पादन के लिए तैयार है।
रिफ्लेक्स में हर सप्ताह नई रिलीज़ और सुविधाएँ आ रही हैं! अपडेट रहने के लिए इस रिपॉजिटरी को :star: स्टार करें और समय-समय पर अवश्य देखें :eyes:।
Reflex में हर सप्ताह नए रिलीज़ और फीचर्स आ रहे हैं! सुनिश्चित करें कि ⭐ स्टार और 👀 वॉच इस रेपोजिटरी को अपडेट रहने के लिए।
## (योगदान) Contributing
हम हर तरह के योगदान का स्वागत करते हैं! रिफ्लेक्स कम्यूनिटी में शुरुआत करने के कुछ अच्छे तरीके नीचे दिए गए हैं।
- **Join Our Discord** (डिस्कॉर्ड सर्वर से जुड़ें): Our [Discord](https://discord.gg/T5WSbC2YtQ) हमारा डिस्कॉर्ड रिफ्लेक्स प्रोजेक्ट पर सहायता प्राप्त करने और आप कैसे योगदान दे सकते हैं, इस पर चर्चा करने के लिए सबसे अच्छी जगह है।
- **GitHub Discussions** (गिटहब चर्चाएँ): उन सुविधाओं के बारे में बात करने का एक शानदार तरीका जिन्हें आप जोड़ना चाहते हैं या ऐसी चीज़ें जो भ्रमित करने वाली हैं/स्पष्टीकरण की आवश्यकता है।
- **GitHub Issues** (गिटहब समस्याएं): ये बग की रिपोर्ट करने का एक शानदार तरीका है। इसके अतिरिक्त, आप किसी मौजूदा समस्या को हल करने का प्रयास कर सकते हैं और एक पीआर सबमिट कर सकते हैं।
- **Join Our Discord** (डिस्कॉर्ड सर्वर से जुड़ें): Our [Discord](https://discord.gg/T5WSbC2YtQ) हमारा डिस्कॉर्ड रिफ्लेक्स प्रोजेक्ट पर सहायता प्राप्त करने और आप कैसे योगदान दे सकते हैं, इस पर चर्चा करने के लिए सबसे अच्छी जगह है।
- **GitHub Discussions** (गिटहब चर्चाएँ): उन सुविधाओं के बारे में बात करने का एक शानदार तरीका जिन्हें आप जोड़ना चाहते हैं या ऐसी चीज़ें जो भ्रमित करने वाली हैं/स्पष्टीकरण की आवश्यकता है।
- **GitHub Issues** (गिटहब समस्याएं): ये [बग](https://github.com/reflex-dev/reflex/issues) की रिपोर्ट करने का एक शानदार तरीका है। इसके अतिरिक्त, आप किसी मौजूदा समस्या को हल करने का प्रयास कर सकते हैं और एक पीआर सबमिट कर सकते हैं।
हम सक्रिय रूप से योगदानकर्ताओं की तलाश कर रहे हैं, चाहे आपका कौशल स्तर या अनुभव कुछ भी हो।
हम सक्रिय रूप से योगदानकर्ताओं की तलाश कर रहे हैं, चाहे आपका कौशल स्तर या अनुभव कुछ भी हो।योगदान करने के लिए [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md) देखें।
## हमारे सभी योगदानकर्ताओं का धन्यवाद:
<a href="https://github.com/reflex-dev/reflex/graphs/contributors">
<img src="https://contrib.rocks/image?repo=reflex-dev/reflex" />
</a>
## लाइसेंस (License)
रिफ्लेक्स ओपन-सोर्स है और [अपाचे लाइसेंस 2.0] (लाइसेंस) के तहत लाइसेंस प्राप्त है।
रिफ्लेक्स ओपन-सोर्स है और [अपाचे लाइसेंस 2.0](https://github.com/reflex-dev/reflex/blob/main/LICENSE) के तहत लाइसेंस प्राप्त है।

View File

@ -10,7 +10,6 @@
### **✨ App web performanti e personalizzabili in puro Python. Distribuisci in pochi secondi. ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![tests](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentaiton](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
@ -18,12 +17,12 @@
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) |
[Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md)
[Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
## ⚙️ Installazione
Apri un terminale ed esegui (Richiede Python 3.8+):
Apri un terminale ed esegui (Richiede Python 3.10+):
```bash
pip install reflex

View File

@ -8,34 +8,36 @@
<hr>
### **✨ 即時デプロイが可能な、Pure Pythonで作ったパフォーマンスと汎用性が高いWebアプリケーション✨**
### **✨ 即時デプロイが可能な、Pure Python で作ったパフォーマンスと汎用性が高い Web アプリケーション ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![tests](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentation](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md)
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
# Reflex
ReflexはPythonのみでフルスタックWebアプリケーションを作成できるライブラリです。
Reflex Python のみでフルスタック Web アプリケーションを作成できるライブラリです。
主な特徴:
* **Pure Python** - WebアプリケーションのフロントエンドとバックエンドをPythonのみで実装できるため、Javascriptを学ぶ必要がありません。
* **高い柔軟性** - Reflexは簡単に始められて、複雑なアプリケーションまで作成できます。
* **即時デプロイ** - ビルド後、すぐにデプロイが可能です。[単純なCLIコマンド](https://reflex.dev/docs/hosting/deploy-quick-start/)を使ったアプリケーションのデプロイや、自身のサーバーへのホストができます。
Reflexがどのように動作しているかを知るには、[アーキテクチャページ](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture)をご覧ください。
- **Pure Python** - Web アプリケーションのフロントエンドとバックエンドを Python のみで実装できるため、Javascript を学ぶ必要がありません。
- **高い柔軟性** - Reflex は簡単に始められて、複雑なアプリケーションまで作成できます。
- **即時デプロイ** - ビルド後、すぐにデプロイが可能です。[単純な CLI コマンド](https://reflex.dev/docs/hosting/deploy-quick-start/)を使ったアプリケーションのデプロイや、自身のサーバーへのホストができます。
Reflex がどのように動作しているかを知るには、[アーキテクチャページ](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture)をご覧ください。
## ⚙️ インストール
ターミナルを開いて以下のコマンドを実行してください。Python 3.8以上が必要です。):
ターミナルを開いて以下のコマンドを実行してください。Python 3.10 以上が必要です。):
```bash
pip install reflex
@ -43,7 +45,7 @@ pip install reflex
## 🥳 最初のアプリケーションを作ろう
`reflex`をインストールすると、`reflex`のCLIツールが自動でインストールされます。
`reflex`をインストールすると、`reflex`の CLI ツールが自動でインストールされます。
新しいプロジェクトを作成して、インストールが成功しているかを確認しましょう。(`my_app_name`を自身のプロジェクト名に書き換えて実行ください。):
@ -63,11 +65,11 @@ reflex run
http://localhost:3000 にアクセスしてアプリの動作を見ることができます。
`my_app_name/my_app_name.py`のソースコードを編集してみましょうReflexはfast refreshなので、ソースを保存した直後に変更がWebページに反映されます。
`my_app_name/my_app_name.py`のソースコードを編集してみましょうReflex fast refresh なので、ソースを保存した直後に変更が Web ページに反映されます。
## 🫧 実装例
実装例を見てみましょう: [DALL·E](https://platform.openai.com/docs/guides/images/image-generation?context=node)を中心とした画像生成UIを作成しました。説明を簡単にするためにここでは[OpenAI API](https://platform.openai.com/docs/api-reference/authentication)を呼んでいますが、ローカルで動作している機械学習モデルに置き換えることも可能です。
実装例を見てみましょう: [DALL·E](https://platform.openai.com/docs/guides/images/image-generation?context=node)を中心とした画像生成 UI を作成しました。説明を簡単にするためにここでは[OpenAI API](https://platform.openai.com/docs/api-reference/authentication)を呼んでいますが、ローカルで動作している機械学習モデルに置き換えることも可能です。
&nbsp;
@ -77,7 +79,7 @@ http://localhost:3000 にアクセスしてアプリの動作を見ることが
&nbsp;
画像生成UIのソースコードの全貌を見てみましょう。下記のように、単一のPythonファイルで作れます
画像生成 UI のソースコードの全貌を見てみましょう。下記のように、単一の Python ファイルで作れます!
```python
import reflex as rx
@ -117,14 +119,15 @@ def index():
on_blur=State.set_prompt,
width="25em",
),
rx.button("Generate Image", on_click=State.get_image, width="25em"),
rx.button(
"Generate Image",
on_click=State.get_image,
width="25em",
loading=State.processing
),
rx.cond(
State.processing,
rx.chakra.circular_progress(is_indeterminate=True),
rx.cond(
State.complete,
rx.image(src=State.image_url, width="20em"),
),
State.complete,
rx.image(src=State.image_url, width="20em"),
),
align="center",
),
@ -137,17 +140,15 @@ app = rx.App()
app.add_page(index, title="Reflex:DALL-E")
```
## それぞれの実装を見てみましょう
<div align="center">
<img src="../../docs/images/dalle_colored_code_example.png" alt="DALL-E appのフロントエンドとバックエンドのパーツの違いを説明しています。" width="900" />
</div>
### **Reflex UI**
UIから見てみましょう。
UI から見てみましょう。
```python
def index():
@ -158,13 +159,13 @@ def index():
`index`関数において、アプリのフロントエンドを定義しています。
フロントエンドを実装するにあたり、`center`、`vstack`、`input`、`button`など異なるコンポーネントを使用しています。コンポーネントはお互いにネストが可能であり、複雑なレイアウトを作成できます。また、keyword argsを使うことで、CSSの機能をすべて使ったスタイルが可能です。
フロントエンドを実装するにあたり、`center`、`vstack`、`input`、`button`など異なるコンポーネントを使用しています。コンポーネントはお互いにネストが可能であり、複雑なレイアウトを作成できます。また、keyword args を使うことで、CSS の機能をすべて使ったスタイルが可能です。
Reflexは[60を超える内臓コンポーネント](https://reflex.dev/docs/library)があるため、すぐに始められます。私たちは、積極的にコンポーネントを追加していますが、簡単に[自身のコンポーネントを追加](https://reflex.dev/docs/wrapping-react/overview/)することも可能です。
Reflex は[60 を超える内臓コンポーネント](https://reflex.dev/docs/library)があるため、すぐに始められます。私たちは、積極的にコンポーネントを追加していますが、簡単に[自身のコンポーネントを追加](https://reflex.dev/docs/wrapping-react/overview/)することも可能です。
### **ステート**
Reflexはステートの関数を用いてUIを表示します。
Reflex はステートの関数を用いて UI を表示します。
```python
class State(rx.State):
@ -176,9 +177,9 @@ class State(rx.State):
```
ステートでは、アプリで変更が可能な全ての変数varsと呼びますと、varsの変更が可能な関数を定義します。
ステートでは、アプリで変更が可能な全ての変数vars と呼びますと、vars の変更が可能な関数を定義します。
この例では、ステートを`prompt`と`image_url`で構成しています。そして、ブール型の`processing`と`complete`を用いて、プログレスサークルと画像の表示を切り替えています。
この例では、ステートを`prompt`と`image_url`で構成しています。そして、ブール型の`processing`と`complete`を用いて、ボタンを無効にするタイミング(画像生成中)や生成された画像を表示するタイミングを示しています。
### **イベントハンドラ**
@ -197,9 +198,9 @@ def get_image(self):
self.processing, self.complete = False, True
```
ステートにおいて、ステートのvarsを変更できるイベントハンドラ関数を定義しています。イベントハンドラはReflexにおいて、ステートのvarsを変更する方法です。ボタンクリックやテキストボックスの入力など、ユーザのアクションに応じてイベントハンドラが呼ばれます。
ステートにおいて、ステートの vars を変更できるイベントハンドラ関数を定義しています。イベントハンドラは Reflex において、ステートの vars を変更する方法です。ボタンクリックやテキストボックスの入力など、ユーザのアクションに応じてイベントハンドラが呼ばれます。
DALL·E.アプリには、OpenAI APIからイメージを取得する`get_image`関数があります。イベントハンドラの最後でUIの更新がかかるため、関数の途中に`yield`を入れることで先にUIを更新しています。
DALL·E.アプリには、OpenAI API からイメージを取得する`get_image`関数があります。イベントハンドラの最後で UI の更新がかかるため、関数の途中に`yield`を入れることで先に UI を更新しています。
### **ルーティング**
@ -209,7 +210,7 @@ DALL·E.アプリには、OpenAI APIからイメージを取得する`get_image`
app = rx.App()
```
アプリにページを追加し、ドキュメントルートをindexコンポーネントにルーティングしています。更に、ページのプレビューやブラウザタブに表示されるタイトルを記載しています。
アプリにページを追加し、ドキュメントルートを index コンポーネントにルーティングしています。更に、ページのプレビューやブラウザタブに表示されるタイトルを記載しています。
```python
app.add_page(index, title="DALL-E")
@ -221,35 +222,34 @@ app.add_page(index, title="DALL-E")
<div align="center">
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Gallery](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy-quick-start) &nbsp;
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Templates](https://reflex.dev/templates/) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy-quick-start) &nbsp;
</div>
## ✅ ステータス
2022年12月に、ReflexはPyneconeという名前でローンチしました。
2022 12 月に、Reflex Pynecone という名前でローンチしました。
2024年2月に、ホスティングサービスをアルファ版でリリースしましたアルファ版では、だれでもReflexアプリケーションを無料でデプロイできます。今後の予定は[ロードマップ](https://github.com/reflex-dev/reflex/issues/2727)において見れます。
2024 2 月に、ホスティングサービスをアルファ版でリリースしました!アルファ版では、だれでも Reflex アプリケーションを無料でデプロイできます。今後の予定は[ロードマップ](https://github.com/reflex-dev/reflex/issues/2727)において見れます。
Reflexは毎週、新しいリリースや機能追加を行っています最新情報を逃さないために、 :star: Starや :eyes: Watchをお願いします。
Reflex は毎週、新しいリリースや機能追加を行っています!最新情報を逃さないために、 :star: Star や :eyes: Watch をお願いします。
## コントリビュート
様々なサイズのコントリビュートを歓迎していますReflexコミュニティに入るための方法を、いくつかリストアップします。
様々なサイズのコントリビュートを歓迎していますReflex コミュニティに入るための方法を、いくつかリストアップします。
- **Discordに参加**: [Discord](https://discord.gg/T5WSbC2YtQ)は、Reflexプロジェクトの相談や、コントリビュートについての話し合いをするための、最適な場所です。
- **GitHub Discussions**: GitHub Discussionsでは、追加したい機能や、複雑で解明が必要な事柄についての議論に適している場所です。
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/issues)はバグの報告に適している場所です。また、課題を解決したPRのサブミットにチャレンジしていただくことも、可能です。
スキルや経験に関わらず、私たちはコントリビュータを積極的に探しています。コントリビュートするために、[CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)をご覧ください。
- **Discord に参加**: [Discord](https://discord.gg/T5WSbC2YtQ)は、Reflex プロジェクトの相談や、コントリビュートについての話し合いをするための、最適な場所です。
- **GitHub Discussions**: GitHub Discussions では、追加したい機能や、複雑で解明が必要な事柄についての議論に適している場所です。
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/issues)はバグの報告に適している場所です。また、課題を解決した PR のサブミットにチャレンジしていただくことも、可能です。
CONTスキルや経験に関わらず、私たちはコントリビュータを積極的に探しています。コントリビュートするために、[CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)をご覧ください。
## 私たちのコントリビュータに感謝!:
<a href="https://github.com/reflex-dev/reflex/graphs/contributors">
<img src="https://contrib.rocks/image?repo=reflex-dev/reflex" />
</a>
## ライセンス
Reflexはオープンソースであり、[Apache License 2.0](LICENSE)に基づいてライセンス供与されます。
Reflex はオープンソースであり、[Apache License 2.0](LICENSE)に基づいてライセンス供与されます。

View File

@ -10,18 +10,17 @@
### **✨ 순수 Python으로 고성능 사용자 정의 웹앱을 만들어 보세요. 몇 초만에 배포 가능합니다. ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![tests](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentaiton](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md)
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
## ⚙️ 설치
터미널을 열고 실행하세요. (Python 3.8+ 필요):
터미널을 열고 실행하세요. (Python 3.10+ 필요):
```bash
pip install reflex
@ -70,10 +69,12 @@ http://localhost:3000 에서 앱이 실행 됩니다.
import reflex as rx
import openai
openai.api_key = "YOUR_API_KEY"
openai_client = openai.OpenAI()
class State(rx.State):
"""The app state."""
prompt = ""
image_url = ""
processing = False
@ -86,33 +87,33 @@ class State(rx.State):
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"]
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"),
rx.input(placeholder="Enter a prompt", on_blur=State.set_prompt),
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",
"Generate Image",
on_click=State.get_image,
is_loading=State.processing,
width="100%",
width="25em",
loading=State.processing
),
rx.cond(
State.complete,
rx.image(
src=State.image_url,
height="25em",
width="25em",
)
rx.image(src=State.image_url, width="20em"),
),
padding="2em",
shadow="lg",
border_radius="lg",
align="center",
),
width="100%",
height="100vh",
@ -120,7 +121,7 @@ def index():
# Add state and page to the app.
app = rx.App()
app.add_page(index, title="reflex:DALL·E")
app.add_page(index, title="Reflex:DALL-E")
```
## 하나씩 살펴보겠습니다.
@ -160,7 +161,7 @@ class State(rx.State):
state는 앱에서 변경될 수 있는 모든 변수(vars로 불림)와 이러한 변수를 변경하는 함수를 정의합니다.
여기서 state는 `prompt``image_url`로 구성됩니다. 또한 `processing``complete`라는 불리언 값이 있습니다. 이 값들은 원형 진행률과 이미지를 표시할 때를 나타냅니다.
여기서 state는 `prompt``image_url`로 구성됩니다. 또한 `processing``complete`라는 불리언 값이 있습니다. 이 값들은 이미지 생성 중 버튼을 비활성화할 때와, 결과 이미지를 표시할 때를 나타냅니다.
### **Event Handlers**
@ -172,8 +173,10 @@ def get_image(self):
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"]
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
```

262
docs/pe/README.md Normal file
View File

@ -0,0 +1,262 @@
```diff
+ دنبال Pynecone میگردی؟ شما در مخزن درستی قرار داری. Pynecone به Reflex تغییر نام داده است. +
```
<div align="center">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_dark.svg#gh-light-mode-only" alt="Reflex Logo" width="300px">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_light.svg#gh-dark-mode-only" alt="Reflex Logo" width="300px">
<hr>
### **✨ برنامه های تحت وب قابل تنظیم، کارآمد تماما پایتونی که در چند ثانیه مستقر(دپلوی) می‎شود. ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentation](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
# Reflex - رفلکس
رفلکس(Reflex) یک کتابخانه برای ساخت برنامه های وب فول استک تماما پایتونی است.
ویژگی های کلیدی:
* **تماما پایتونی** - فرانت اند و بک اند برنامه خود را همه در پایتون بنویسید، بدون نیاز به یادگیری جاوا اسکریپت.
* **انعطاف پذیری کامل** - شروع به کار با Reflex آسان است، اما می تواند به برنامه های پیچیده نیز تبدیل شود.
* **دپلوی فوری** - پس از ساخت، برنامه خود را با [یک دستور](https://reflex.dev/docs/hosting/deploy-quick-start/) دپلوی کنید یا آن را روی سرور خود میزبانی کنید.
برای آشنایی با نحوه عملکرد Reflex [صفحه معماری](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture) را ببینید.
## ⚙️ Installation - نصب و راه اندازی
یک ترمینال را باز کنید و اجرا کنید (نیازمند Python 3.10+):
```bash
pip install reflex
```
## 🥳 اولین برنامه خود را ایجاد کنید
نصب `reflex` همچنین `reflex` در خط فرمان را نصب میکند.
با ایجاد یک پروژه جدید موفقیت آمیز بودن نصب را تست کنید. (`my_app_name` را با اسم پروژه خودتان جایگزین کنید):
```bash
mkdir my_app_name
cd my_app_name
reflex init
```
این دستور یک برنامه الگو(تمپلیت) را در فهرست(دایرکتوری) جدید شما مقداردهی اولیه می کند
می توانید این برنامه را در حالت توسعه(development) اجرا کنید:
```bash
reflex run
```
باید برنامه خود را در حال اجرا ببینید در http://localhost:3000.
اکنون می‌توانید کد منبع را در «my_app_name/my_app_name.py» تغییر دهید. Reflex دارای تازه‌سازی‌های سریعی است، بنابراین می‌توانید تغییرات خود را بلافاصله پس از ذخیره کد خود مشاهده کنید.
## 🫧 Example App - برنامه نمونه
بیایید یک مثال بزنیم: ایجاد یک رابط کاربری برای تولید تصویر [DALL·E](https://platform.openai.com/docs/guides/images/image-generation?context=node). برای سادگی، ما فراخوانی میکنیم [OpenAI API](https://platform.openai.com/docs/api-reference/authentication), اما می توانید آن را با یک مدل ML که به صورت محلی اجرا می شود جایگزین کنید.
&nbsp;
<div align="center">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/dalle.gif" alt="A frontend wrapper for DALL·E, shown in the process of generating an image." width="550" />
</div>
&nbsp;
در اینجا کد کامل برای ایجاد این پروژه آمده است. همه اینها در یک فایل پایتون انجام می شود!
```python
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")
```
## بیاید سادش کنیم
<div align="center">
<img src="docs/images/dalle_colored_code_example.png" alt="Explaining the differences between backend and frontend parts of the DALL-E app." width="900" />
</div>
### **Reflex UI - رابط کاربری رفلکس**
بیایید با رابط کاربری شروع کنیم.
```python
def index():
return rx.center(
...
)
```
تابع `index` قسمت فرانت اند برنامه را تعریف می کند.
ما از اجزای مختلفی مثل `center`, `vstack`, `input` و `button` استفاده میکنیم تا فرانت اند را بسازیم. اجزاء را می توان درون یکدیگر قرار داد
برای ایجاد طرح بندی های پیچیده می توانید از args کلمات کلیدی برای استایل دادن به آنها از CSS استفاده کنید.
رفلکس دارای [بیش از 60 جزء](https://reflex.dev/docs/library) برای کمک به شما برای شروع. ما به طور فعال اجزای بیشتری را اضافه می کنیم, و این خیلی آسان است که [اجزا خود را بسازید](https://reflex.dev/docs/wrapping-react/overview/).
### **State - حالت**
رفلکس رابط کاربری شما را به عنوان تابعی از وضعیت شما نشان می دهد.
```python
class State(rx.State):
"""The app state."""
prompt = ""
image_url = ""
processing = False
complete = False
```
حالت تمام متغیرها(variables) (به نام vars) را در یک برنامه که می توانند تغییر دهند و توابعی که آنها را تغییر می دهند تعریف می کند..
در اینجا حالت از یک `prompt` و `image_url` تشکیل شده است. همچنین دو بولی `processing` و `complete` برای نشان دادن زمان غیرفعال کردن دکمه (در طول تولید تصویر) و زمان نمایش تصویر نتیجه وجود دارد.
### **Event Handlers - کنترل کنندگان رویداد**
```python
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
```
در داخل حالت، توابعی به نام کنترل کننده رویداد تعریف می کنیم که متغیرهای حالت را تغییر می دهند. کنترل کننده های رویداد راهی هستند که می توانیم وضعیت را در Reflex تغییر دهیم. آنها را می توان در پاسخ به اقدامات کاربر، مانند کلیک کردن روی یک دکمه یا تایپ کردن در یک متن، فراخوانی کرد. به این اعمال وقایع می گویند.
برنامه DALL·E ما دارای یک کنترل کننده رویداد، `get_image` است که این تصویر را از OpenAI API دریافت می کند. استفاده از `yield` در وسط کنترل‌کننده رویداد باعث به‌روزرسانی رابط کاربری می‌شود. در غیر این صورت رابط کاربری در پایان کنترل کننده رویداد به روز می شود.
### **Routing - مسیریابی**
بالاخره اپلیکیشن خود را تعریف می کنیم.
```python
app = rx.App()
```
ما یک صفحه از root برنامه را به جزء index اضافه می کنیم. ما همچنین عنوانی را اضافه می کنیم که در برگه پیش نمایش/مرورگر صفحه نمایش داده می شود.
```python
app.add_page(index, title="DALL-E")
```
با افزودن صفحات بیشتر می توانید یک برنامه چند صفحه ای ایجاد کنید.
## 📑 Resources - منابع
<div align="center">
📑 [اسناد](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [وبلاگ](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [کتابخانه جزء](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [گالری](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [استقرار](https://reflex.dev/docs/hosting/deploy-quick-start) &nbsp;
</div>
## ✅ Status - وضعیت
رفلکس(reflex) در دسامبر 2022 با نام Pynecone راه اندازی شد.
از فوریه 2024، سرویس میزبانی ما در آلفا است! در این مدت هر کسی می‌تواند برنامه‌های خود را به صورت رایگان اجرا کند. [نقشه راه](https://github.com/reflex-dev/reflex/issues/2727) را ببینید تا متوجه شوید چه برنامه‌ریزی شده است.
رفلکس(reflex) هر هفته نسخه ها و ویژگی های جدیدی دارد! مطمئن شوید که :star: ستاره و :eyes: این مخزن را تماشا کنید تا به روز بمانید.
## Contributing - مشارکت کردن
ما از مشارکت در هر اندازه استقبال می کنیم! در زیر چند راه خوب برای شروع در انجمن رفلکس آورده شده است.
- **به Discord ما بپیوندید**: [Discord](https://discord.gg/T5WSbC2YtQ) ما بهترین مکان برای دریافت کمک در مورد پروژه Reflex و بحث در مورد اینکه چگونه می توانید کمک کنید است.
- **بحث های GitHub**: راهی عالی برای صحبت در مورد ویژگی هایی که می خواهید اضافه کنید یا چیزهایی که گیج کننده هستند/نیاز به توضیح دارند.
- **قسمت مشکلات GitHub**: [قسمت مشکلات](https://github.com/reflex-dev/reflex/issues) یک راه عالی برای گزارش اشکال هستند. علاوه بر این، می توانید یک مشکل موجود را حل کنید و یک PR(pull request) ارسال کنید.
ما فعالانه به دنبال مشارکت کنندگان هستیم، فارغ از سطح مهارت یا تجربه شما. برای مشارکت [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md) را بررسی کنید.
## All Thanks To Our Contributors - با تشکر از همکاران ما:
<a href="https://github.com/reflex-dev/reflex/graphs/contributors">
<img src="https://contrib.rocks/image?repo=reflex-dev/reflex" />
</a>
## License - مجوز
رفلکس متن باز و تحت مجوز [Apache License 2.0](LICENSE) است.

View File

@ -17,11 +17,11 @@
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md)
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
## ⚙️ Instalação
Abra um terminal e execute (Requer Python 3.8+):
Abra um terminal e execute (Requer Python 3.10+):
```bash
pip install reflex

View File

@ -11,7 +11,6 @@
### **✨ Saf Python'da performanslı, özelleştirilebilir web uygulamaları. Saniyeler içinde dağıtın. ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![tests](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentaiton](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
@ -19,13 +18,13 @@
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md)
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
## ⚙️ Kurulum
Bir terminal açın ve çalıştırın (Python 3.8+ gerekir):
Bir terminal açın ve çalıştırın (Python 3.10+ gerekir):
```bash
pip install reflex
@ -201,7 +200,7 @@ Daha fazla sayfa ekleyerek çok sayfalı bir uygulama oluşturabilirsiniz.
<div align="center">
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Gallery](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy) &nbsp;
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Templates](https://reflex.dev/templates/) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy) &nbsp;
</div>
@ -230,7 +229,7 @@ Her boyuttaki katkıları memnuniyetle karşılıyoruz! Aşağıda Reflex toplul
- **GitHub Discussions**: Eklemek istediğiniz özellikler veya kafa karıştırıcı, açıklığa kavuşturulması gereken şeyler hakkında konuşmanın harika bir yolu.
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/issues) hataları bildirmenin mükemmel bir yoludur. Ayrıca mevcut bir sorunu deneyip çözebilir ve bir PR (Pull Requests) gönderebilirsiniz.
Beceri düzeyiniz veya deneyiminiz ne olursa olsun aktif olarak katkıda bulunacak kişiler arıyoruz. Katkı sağlamak için katkı sağlama rehberimize bakabilirsiniz: [CONTIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
Beceri düzeyiniz veya deneyiminiz ne olursa olsun aktif olarak katkıda bulunacak kişiler arıyoruz. Katkı sağlamak için katkı sağlama rehberimize bakabilirsiniz: [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
## Hepsi Katkıda Bulunanlar Sayesinde:

267
docs/vi/README.md Normal file
View File

@ -0,0 +1,267 @@
```diff
+ Bạn đang tìm kiếm Pynecone? Bạn đã tìm đúng. Pynecone đã được đổi tên thành Reflex. +
```
<div align="center">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_dark.svg#gh-light-mode-only" alt="Reflex Logo" width="300px">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/reflex_light.svg#gh-dark-mode-only" alt="Reflex Logo" width="300px">
<hr>
### **✨ Ứng dụng web hiệu suất cao, tùy chỉnh bằng Python thuần. Deploy trong vài giây. ✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentation](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md) | [Tiếng Việt](https://github.com/reflex-dev/reflex/blob/main/docs/vi/README.md)
---
# Reflex
Reflex là một thư viện để xây dựng ứng dụng web toàn bộ bằng Python thuần.
Các tính năng chính:
* **Python thuần tuý** - Viết toàn bộ ứng dụng cả backend và frontend hoàn toàn bằng Python, không cần học JavaScript.
* **Full Flexibility** - Reflex dễ dàng để bắt đầu, nhưng cũng có thể mở rộng lên các ứng dụng phức tạp.
* **Deploy Instantly** - Sau khi xây dựng ứng dụng, bạn có thể triển khai bằng [một dòng lệnh](https://reflex.dev/docs/hosting/deploy-quick-start/) hoặc triển khai trên server của riêng bạn.
Đọc [bài viết về kiến trúc hệ thống](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture) để hiểu rõ các hoạt động của Reflex.
## ⚙️ Cài đặt
Mở cửa sổ lệnh và chạy (Yêu cầu Python phiên bản 3.10+):
```bash
pip install reflex
```
## 🥳 Tạo ứng dụng đầu tiên
Cài đặt `reflex` cũng như cài đặt công cụ dòng lệnh `reflex`.
Kiểm tra việc cài đặt đã thành công hay chưa bằng cách tạo mới một ứng dụng. (Thay `my_app_name` bằng tên ứng dụng của bạn):
```bash
mkdir my_app_name
cd my_app_name
reflex init
```
Lệnh này tạo ra một ứng dụng mẫu trong một thư mục mới.
Bạn có thể chạy ứng dụng ở chế độ phát triển.
```bash
reflex run
```
Bạn có thể xem ứng dụng của bạn ở địa chỉ http://localhost:3000.
Bạn có thể thay đổi mã nguồn ở `my_app_name/my_app_name.py`. Reflex nhanh chóng làm mới và bạn có thể thấy thay đổi trên ứng dụng của bạn ngay lập tức khi bạn lưu file.
## 🫧 Ứng dụng ví dụ
Bắt đầu với ví dụ: tạo một ứng dụng tạo ảnh bằng [DALL·E](https://platform.openai.com/docs/guides/images/image-generation?context=node). Để cho đơn giản, chúng ta sẽ sử dụng [OpenAI API](https://platform.openai.com/docs/api-reference/authentication), nhưng bạn có thể sử dụng model của chính bạn được triển khai trên local.
&nbsp;
<div align="center">
<img src="https://raw.githubusercontent.com/reflex-dev/reflex/main/docs/images/dalle.gif" alt="A frontend wrapper for DALL·E, shown in the process of generating an image." width="550" />
</div>
&nbsp;
Đây là toàn bộ đoạn mã để xây dựng ứng dụng trên. Nó được viết hoàn toàn trong một file Python!
```python
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")
```
## Hãy phân tích chi tiết.
<div align="center">
<img src="../images/dalle_colored_code_example.png" alt="Explaining the differences between backend and frontend parts of the DALL-E app." width="900" />
</div>
### **Reflex UI**
Bắt đầu với giao diện chính.
```python
def index():
return rx.center(
...
)
```
Hàm `index` định nghĩa phần giao diện chính của ứng dụng.
Chúng tôi sử dụng các component (thành phần) khác nhau như `center`, `vstack`, `input``button` để xây dựng giao diện phía trước.
Các component có thể được lồng vào nhau để tạo ra các bố cục phức tạp. Và bạn cũng có thể sử dụng từ khoá `args` để tận dụng đầy đủ sức mạnh của CSS.
Reflex có đến hơn [60 component được xây dựng sẵn](https://reflex.dev/docs/library) để giúp bạn bắt đầu. Chúng ta có thể tạo ra một component mới khá dễ dàng, thao khảo: [xây dựng component của riêng bạn](https://reflex.dev/docs/wrapping-react/overview/).
### **State**
Reflex biểu diễn giao diện bằng các hàm của state (trạng thái).
```python
class State(rx.State):
"""The app state."""
prompt = ""
image_url = ""
processing = False
complete = False
```
Một state định nghĩa các biến (được gọi là vars) có thể thay đổi trong một ứng dụng và cho phép các hàm có thể thay đổi chúng.
Tại đây state được cấu thành từ một `prompt``image_url`.
Có cũng những biến boolean `processing``complete`
để chỉ ra khi nào tắt nút (trong quá trình tạo hình ảnh)
và khi nào hiển thị hình ảnh kết quả.
### **Event Handlers**
```python
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
```
Với các state, chúng ta định nghĩa các hàm có thể thay đổi state vars được gọi là event handlers. Event handler là cách chúng ta có thể thay đổi state trong Reflex. Chúng có thể là phản hồi khi người dùng thao tác, chằng hạn khi nhấn vào nút hoặc khi đang nhập trong text box. Các hành động này được gọi là event.
Ứng dụng DALL·E. của chúng ta có một event handler, `get_image` để lấy hình ảnh từ OpenAI API. Sử dụng từ khoá `yield` in ở giữa event handler để cập nhật giao diện. Hoặc giao diện có thể cập nhật ở cuối event handler.
### **Routing**
Cuối cùng, chúng ta định nghĩa một ứng dụng.
```python
app = rx.App()
```
Chúng ta thêm một trang ở đầu ứng dụng bằng index component. Chúng ta cũng thêm tiêu đề của ứng dụng để hiển thị lên trình duyệt.
```python
app.add_page(index, title="DALL-E")
```
Bạn có thể tạo một ứng dụng nhiều trang bằng cách thêm trang.
## 📑 Tài liệu
<div align="center">
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Templates](https://reflex.dev/templates/) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy-quick-start) &nbsp;
</div>
## ✅ Status
Reflex phát hành vào tháng 12/2022 với tên là Pynecone.
Đến tháng 02/2024, chúng tôi tạo ra dịch vụ dưới phiên bản alpha! Trong thời gian này mọi người có thể triển khai ứng dụng hoàn toàn miễn phí. Xem [roadmap](https://github.com/reflex-dev/reflex/issues/2727) để biết thêm chi tiết.
Reflex ra phiên bản mới với các tính năng mới hàng tuần! Hãy :star: star và :eyes: watch repo này để thấy các cập nhật mới nhất.
## Contributing
Chúng tôi chào đón mọi đóng góp dù lớn hay nhỏ. Dưới đây là các cách để bắt đầu với cộng đồng Reflex.
- **Discord**: [Discord](https://discord.gg/T5WSbC2YtQ) của chúng tôi là nơi tốt nhất để nhờ sự giúp đỡ và thảo luận các bạn có thể đóng góp.
- **GitHub Discussions**: Là cách tốt nhất để thảo luận về các tính năng mà bạn có thể đóng góp hoặc những điều bạn chưa rõ.
- **GitHub Issues**: [Issues](https://github.com/reflex-dev/reflex/issues) là nơi tốt nhất để thông báo. Ngoài ra bạn có thể sửa chữa các vấn đề bằng cách tạo PR.
Chúng tôi luôn sẵn sàng tìm kiếm các contributor, bất kể kinh nghiệm. Để tham gia đóng góp, xin mời xem
[CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
## Xin cảm ơn các Contributors:
<a href="https://github.com/reflex-dev/reflex/graphs/contributors">
<img src="https://contrib.rocks/image?repo=reflex-dev/reflex" />
</a>
## License
Reflex là mã nguồn mở và sử dụng giấy phép [Apache License 2.0](LICENSE).

View File

@ -8,25 +8,35 @@
<hr>
**✨ 使用 Python 创建高效且可自定义的网页应用程序,几秒钟内即可部署.**
### **✨ 使用 Python 创建高效且可自定义的网页应用程序,几秒钟内即可部署.✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![tests](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentaiton](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md)
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
# Reflex
Reflex 是一个使用纯Python构建全栈web应用的库。
关键特性:
* **纯Python** - 前端、后端开发全都使用Python不需要学习Javascript。
* **完整的灵活性** - Reflex很容易上手, 并且也可以扩展到复杂的应用程序。
* **立即部署** - 构建后,使用[单个命令](https://reflex.dev/docs/hosting/deploy-quick-start/)就能部署应用程序;或者也可以将其托管在您自己的服务器上。
请参阅我们的[架构页](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture)了解Reflex如何工作。
## ⚙️ 安装
打开一个终端并且运行(要求Python3.8+):
打开一个终端并且运行(要求Python3.10+):
```
```bash
pip install reflex
```
@ -36,7 +46,7 @@ pip install reflex
通过创建一个新项目来测试是否安装成功(请把 my_app_name 替代为您的项目名字):
```
```bash
mkdir my_app_name
cd my_app_name
reflex init
@ -45,6 +55,7 @@ reflex init
这段命令会在新文件夹初始化一个应用程序模板.
您可以在开发者模式下运行这个应用程序:
```bash
reflex run
```
@ -55,7 +66,7 @@ reflex run
## 🫧 范例
让我们来看一个例子: 创建一个使用 DALL·E 进行图像生成的图形界面.为了保持范例简单,我们只使用 OpenAI API,但是您可以将其替换成本地端的 ML 模型.
让我们来看一个例子: 创建一个使用 [DALL·E](https://platform.openai.com/docs/guides/images/image-generation?context=node) 进行图像生成的图形界面.为了保持范例简单,我们只使用 OpenAI API,但是您可以将其替换成本地端的 ML 模型.
&nbsp;
@ -67,14 +78,19 @@ reflex run
这是这个范例的完整代码,只需要一个 Python 文件就可以完成!
```python
import reflex as rx
import openai
openai.api_key = "YOUR_API_KEY"
openai_client = openai.OpenAI()
class State(rx.State):
"""The app state."""
prompt = ""
image_url = ""
processing = False
@ -87,33 +103,33 @@ class State(rx.State):
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"]
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"),
rx.input(placeholder="Enter a prompt", on_blur=State.set_prompt),
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",
"Generate Image",
on_click=State.get_image,
is_loading=State.processing,
width="100%",
width="25em",
loading=State.processing
),
rx.cond(
State.complete,
rx.image(
src=State.image_url,
height="25em",
width="25em",
)
rx.image(src=State.image_url, width="20em"),
),
padding="2em",
shadow="lg",
border_radius="lg",
align="center",
),
width="100%",
height="100vh",
@ -121,11 +137,20 @@ def index():
# Add state and page to the app.
app = rx.App()
app.add_page(index, title="reflex:DALL·E")
app.add_page(index, title="Reflex:DALL-E")
```
## 让我们分解以上步骤.
<div align="center">
<img src="../../images/dalle_colored_code_example.png" alt="解释 DALL-E app 的前端和后端部分的区别。" width="900" />
</div>
### **Reflex UI**
让我们从UI开始.
@ -142,7 +167,7 @@ def index():
我们用不同的组件比如 `center`, `vstack`, `input`, 和 `button` 来创建前端, 组件之间可以相互嵌入,来创建复杂的布局.
并且您可以使用关键字参数来使用 CSS 的全部功能.
Reflex 拥有 [60+ 个内置组件](https://reflex.dev/docs/library) 来帮助您开始创建应用程序. 我们正在积极添加组件, 但是您也可以 [创建自己的组件](https://reflex.dev/docs/wrapping-react/overview/).
Reflex 拥有 [60+ 个内置组件](https://reflex.dev/docs/library) 来帮助您开始创建应用程序. 我们正在积极添加组件, 但是您也可以容易的 [创建自己的组件](https://reflex.dev/docs/wrapping-react/overview/).
### **State**
@ -155,12 +180,12 @@ class State(rx.State):
image_url = ""
processing = False
complete = False
```
```
State定义了所有可能会发生变化的变量(称为 vars)以及能够改变这些变量的函数.
在这个范例中,State由 prompt 和 image_url 组成.此外,State还包含有两个布尔值 processing 和 complete,用于指示何时显示循环进度指示器和图像.
在这个范例中,State由 `prompt``image_url` 组成.此外,State还包含有两个布尔值 `processing``complete`,用于指示何时显示循环进度指示器和图像.
### **Event Handlers**
@ -172,14 +197,16 @@ def get_image(self):
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"]
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
```
在 State 中,我们定义了称为事件处理器(event handlers)的函数,用于改变状态变量(state vars).在Reflex中,事件处理器是我们可以修改状态的方式.它们可以作为对用户操作的响应而被调用,例如点击一个按钮或在文本框中输入.这些操作被称为事件.
我们的DALL·E应用有一个事件处理器,名为 get_image,它用于从OpenAI API获取图像.在事件处理器中使用 yield 将导致UI进行更新.否则,UI将在事件处理器结束时进行更新.
我们的DALL·E应用有一个事件处理器,名为 `get_image`,它用于从OpenAI API获取图像.在事件处理器中使用 `yield` 将导致UI进行更新.否则,UI将在事件处理器结束时进行更新.
### **Routing**
@ -206,19 +233,13 @@ app.add_page(index, title="DALL-E")
</div>
## ✅ Reflex 的状态
Reflex 于 2022 年 12 月以Pynecone的名称推出.
在2023年7月, 我们处于 **Public Beta** 阶段.
截至2024年2月我们的托管服务处于alpha测试阶段在此期间任何人都可以免费部署他们的应用程序。请查看我们的[路线图](https://github.com/reflex-dev/reflex/issues/2727)以了解我们的计划。
- :white_check_mark: **Public Alpha**: 任何人都可以安装与使用 Reflex,或许包含问题, 但我们正在积极的解决他们.
- :large_orange_diamond: **Public Beta**: 对于非软件产品来说足够稳定.
- **Public Hosting Beta**: _Optionally_, 部属跟托管您的 Reflex!
- **Public**: 这版本的 Reflex 是可用于软件产品的.
Reflex 每周都有新功能和发布新版本! 确保您按下 :star: 和 :eyes: watch 这个 repository 来确保知道最新信息.
Reflex 每周都有新功能和发布新版本! 确保您按下 :star: 收藏和 :eyes: 关注 这个 仓库来确保知道最新信息.
## 贡献
@ -226,10 +247,16 @@ Reflex 每周都有新功能和发布新版本! 确保您按下 :star: 和 :eyes
- **加入我们的 Discord**: 我们的 [Discord](https://discord.gg/T5WSbC2YtQ) 是帮助您加入 Reflex 项目和讨论或贡献最棒的地方.
- **GitHub Discussions**: 一个来讨论您想要添加的功能或是需要澄清的事情的好地方.
- **GitHub Issues**: 报告错误的绝佳地方,另外您可以试着解决一些 issue 和送出 PR.
- **GitHub Issues**: [报告错误](https://github.com/reflex-dev/reflex/issues)的绝佳地方,另外您可以试着解决一些 issue 和送出 PR.
我们正在积极寻找贡献者,无关您的技能或经验水平.
## 感谢我们所有的贡献者:
<a href="https://github.com/reflex-dev/reflex/graphs/contributors">
<img src="https://contrib.rocks/image?repo=reflex-dev/reflex" />
</a>
## 授权
Reflex 是一个开源项目,使用 [Apache License 2.0](LICENSE) 授权.

View File

@ -11,18 +11,32 @@
**✨ 使用 Python 建立高效且可自訂的網頁應用程式,幾秒鐘內即可部署。✨**
[![PyPI version](https://badge.fury.io/py/reflex.svg)](https://badge.fury.io/py/reflex)
![tests](https://github.com/pynecone-io/pynecone/actions/workflows/integration.yml/badge.svg)
![versions](https://img.shields.io/pypi/pyversions/reflex.svg)
[![Documentaiton](https://img.shields.io/badge/Documentation%20-Introduction%20-%20%23007ec6)](https://reflex.dev/docs/getting-started/introduction)
[![Discord](https://img.shields.io/discord/1029853095527727165?color=%237289da&label=Discord)](https://discord.gg/T5WSbC2YtQ)
</div>
---
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md)
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md) | [Türkçe](https://github.com/reflex-dev/reflex/blob/main/docs/tr/README.md) | [हिंदी](https://github.com/reflex-dev/reflex/blob/main/docs/in/README.md) | [Português (Brasil)](https://github.com/reflex-dev/reflex/blob/main/docs/pt/pt_br/README.md) | [Italiano](https://github.com/reflex-dev/reflex/blob/main/docs/it/README.md) | [Español](https://github.com/reflex-dev/reflex/blob/main/docs/es/README.md) | [한국어](https://github.com/reflex-dev/reflex/blob/main/docs/kr/README.md) | [日本語](https://github.com/reflex-dev/reflex/blob/main/docs/ja/README.md) | [Deutsch](https://github.com/reflex-dev/reflex/blob/main/docs/de/README.md) | [Persian (پارسی)](https://github.com/reflex-dev/reflex/blob/main/docs/pe/README.md)
---
# Reflex
Reflex 是一個可以用純 Python 構建全端網頁應用程式的函式庫。
主要特色:
* **純 Python** - 您可以用 Python 撰寫應用程式的前端和後端,無需學習 Javascript。
* **完全靈活性** - Reflex 易於上手,但也可以擴展到複雜的應用程式。
* **立即部署** - 構建後,只需使用[單一指令](https://reflex.dev/docs/hosting/deploy-quick-start/)即可部署您的應用程式,或在您自己的伺服器上託管。
請參閱我們的[架構頁面](https://reflex.dev/blog/2024-03-21-reflex-architecture/#the-reflex-architecture)了解 Reflex 如何在底層運作。
## ⚙️ 安裝
開啟一個終端機並且執行 (需要 Python 3.8+):
開啟一個終端機並且執行 (需要 Python 3.10+):
```bash
pip install reflex
@ -70,7 +84,8 @@ reflex run
import reflex as rx
import openai
openai.api_key = "YOUR_API_KEY"
openai_client = openai.OpenAI()
class State(rx.State):
"""應用程式狀態"""
@ -86,33 +101,33 @@ class State(rx.State):
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"]
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"),
rx.input(placeholder="Enter a prompt", on_blur=State.set_prompt),
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",
"Generate Image",
on_click=State.get_image,
is_loading=State.processing,
width="100%",
width="25em",
loading=State.processing
),
rx.cond(
State.complete,
rx.image(
src=State.image_url,
height="25em",
width="25em",
)
rx.image(src=State.image_url, width="20em"),
),
padding="2em",
shadow="lg",
border_radius="lg",
align="center",
),
width="100%",
height="100vh",
@ -120,10 +135,22 @@ def index():
# 把狀態跟頁面添加到應用程式。
app = rx.App()
app.add_page(index, title="reflex:DALL·E")
app.add_page(index, title="Reflex:DALL-E")
```
## 讓我們來拆解一下。
<div align="center">
<img src="../../images/dalle_colored_code_example.png" alt="解釋 DALL-E app 的前端和後端部分的區別。" width="900" />
</div>
### **Reflex 使用者介面**
讓我們從使用介面開始。
@ -150,8 +177,9 @@ class State(rx.State):
"""應用程式狀態"""
prompt = ""
image_url = ""
image_processing = False
image_made = False
processing = False
complete = False
```
應用程式狀態定義了應用程式中所有可以更改的變數及變更他們的函式 (稱為 vars)。
@ -168,8 +196,10 @@ def get_image(self):
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"]
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
```
@ -199,34 +229,35 @@ app.add_page(index, title="DALL-E")
<div align="center">
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Gallery](https://reflex.dev/docs/gallery) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy) &nbsp;
📑 [Docs](https://reflex.dev/docs/getting-started/introduction) &nbsp; | &nbsp; 🗞️ [Blog](https://reflex.dev/blog) &nbsp; | &nbsp; 📱 [Component Library](https://reflex.dev/docs/library) &nbsp; | &nbsp; 🖼️ [Templates](https://reflex.dev/templates/) &nbsp; | &nbsp; 🛸 [Deployment](https://reflex.dev/docs/hosting/deploy-quick-start) &nbsp;
</div>
## ✅ Reflex 狀態
## ✅ 產品狀態
Reflex 於 2022 年 12 月推出,當時名為 Pynecone
Reflex 在 2022 年 12 月以 Pynecone 的名字推出
截至 2023 年 7 月,我們處於 **Public Beta** 階段。
- :white_check_mark: **Public Alpha**: 任何人都可以安裝與使用 Reflex或許包含問題 但我們正在積極的解決他們。
- :large_orange_diamond: **Public Beta**: 對於不涉及商業目的使用情境來說足夠穩定。
- **Public Hosting Beta**: _Optionally_, 部屬跟託管你的 Reflex!
- **Public**: 這版本的 Reflex 是可用於軟體產品的。
截至 2024 年 2 月,我們的託管服務已進入 alpha 階段!在此期間,任何人都可以免費部署他們的應用程式。請參閱我們的[產品地圖](https://github.com/reflex-dev/reflex/issues/2727)了解未來的計劃。
Reflex 每周都有新功能和釋出新版本! 確保你按下 :star: 和 :eyes: watch 這個 repository 來確保知道最新資訊。
## 貢獻
我們歡迎任何大小的貢獻,以下是幾個好的方法來加入 Reflex 社群
我們歡迎任何大小的貢獻,以下是一些加入 Reflex 社群的好方法
- **加入我們的 Discord**: 我們的 [Discord](https://discord.gg/T5WSbC2YtQ) 是幫助你加入 Reflex 專案和討論或貢獻最棒的地方。
- **GitHub Discussions**: 一個來討論你想要添加的功能或是需要澄清的事情的好地方
- **GitHub Issues**: 報告錯誤的絕佳地方,另外你可以試著解決一些 issue 和送出 PR。
- **加入我們的 Discord**: 我們的 [Discord](https://discord.gg/T5WSbC2YtQ) 是獲取 Reflex 專案幫助和討論如何貢獻的最佳地方。
- **GitHub Discussions**: 這是一個討論您想新增的功能或對於一些困惑/需要澄清事項的好方法
- **GitHub Issues**: 在 [Issues](https://github.com/reflex-dev/reflex/issues) 頁面報告錯誤是一個絕佳的方式。此外,您也可以嘗試解決現有 Issue 並提交 PR。
我們正在積極尋找貢獻者,無關你的技能水平或經驗。
我們積極尋找貢獻者,不論您的技能水平或經驗如何。要貢獻,請查看 [CONTRIBUTING.md](https://github.com/reflex-dev/reflex/blob/main/CONTRIBUTING.md)
## 感謝所有貢獻者:
<a href="https://github.com/reflex-dev/reflex/graphs/contributors">
<img src="https://contrib.rocks/image?repo=reflex-dev/reflex" />
</a>
## 授權

View File

@ -1,211 +0,0 @@
"""Test @rx.background task functionality."""
from typing import Generator
import pytest
from selenium.webdriver.common.by import By
from reflex.testing import DEFAULT_TIMEOUT, AppHarness, WebDriver
def BackgroundTask():
"""Test that background tasks work as expected."""
import asyncio
import reflex as rx
class State(rx.State):
counter: int = 0
_task_id: int = 0
iterations: int = 10
@rx.background
async def handle_event(self):
async with self:
self._task_id += 1
for _ix in range(int(self.iterations)):
async with self:
self.counter += 1
await asyncio.sleep(0.005)
@rx.background
async def handle_event_yield_only(self):
async with self:
self._task_id += 1
for ix in range(int(self.iterations)):
if ix % 2 == 0:
yield State.increment_arbitrary(1) # type: ignore
else:
yield State.increment() # type: ignore
await asyncio.sleep(0.005)
def increment(self):
self.counter += 1
@rx.background
async def increment_arbitrary(self, amount: int):
async with self:
self.counter += int(amount)
def reset_counter(self):
self.counter = 0
async def blocking_pause(self):
await asyncio.sleep(0.02)
@rx.background
async def non_blocking_pause(self):
await asyncio.sleep(0.02)
def index() -> rx.Component:
return rx.vstack(
rx.chakra.input(
id="token", value=State.router.session.client_token, is_read_only=True
),
rx.heading(State.counter, id="counter"),
rx.chakra.input(
id="iterations",
placeholder="Iterations",
value=State.iterations.to_string(), # type: ignore
on_change=State.set_iterations, # type: ignore
),
rx.button(
"Delayed Increment",
on_click=State.handle_event,
id="delayed-increment",
),
rx.button(
"Yield Increment",
on_click=State.handle_event_yield_only,
id="yield-increment",
),
rx.button("Increment 1", on_click=State.increment, id="increment"),
rx.button(
"Blocking Pause",
on_click=State.blocking_pause,
id="blocking-pause",
),
rx.button(
"Non-Blocking Pause",
on_click=State.non_blocking_pause,
id="non-blocking-pause",
),
rx.button("Reset", on_click=State.reset_counter, id="reset"),
)
app = rx.App(state=rx.State)
app.add_page(index)
@pytest.fixture(scope="module")
def background_task(
tmp_path_factory,
) -> Generator[AppHarness, None, None]:
"""Start BackgroundTask app at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
running AppHarness instance
"""
with AppHarness.create(
root=tmp_path_factory.mktemp(f"background_task"),
app_source=BackgroundTask, # type: ignore
) as harness:
yield harness
@pytest.fixture
def driver(background_task: AppHarness) -> Generator[WebDriver, None, None]:
"""Get an instance of the browser open to the background_task app.
Args:
background_task: harness for BackgroundTask app
Yields:
WebDriver instance.
"""
assert background_task.app_instance is not None, "app is not running"
driver = background_task.frontend()
try:
yield driver
finally:
driver.quit()
@pytest.fixture()
def token(background_task: AppHarness, driver: WebDriver) -> str:
"""Get a function that returns the active token.
Args:
background_task: harness for BackgroundTask app.
driver: WebDriver instance.
Returns:
The token for the connected client
"""
assert background_task.app_instance is not None
token_input = driver.find_element(By.ID, "token")
assert token_input
# wait for the backend connection to send the token
token = background_task.poll_for_value(token_input, timeout=DEFAULT_TIMEOUT * 2)
assert token is not None
return token
def test_background_task(
background_task: AppHarness,
driver: WebDriver,
token: str,
):
"""Test that background tasks work as expected.
Args:
background_task: harness for BackgroundTask app.
driver: WebDriver instance.
token: The token for the connected client.
"""
assert background_task.app_instance is not None
# get a reference to all buttons
delayed_increment_button = driver.find_element(By.ID, "delayed-increment")
yield_increment_button = driver.find_element(By.ID, "yield-increment")
increment_button = driver.find_element(By.ID, "increment")
blocking_pause_button = driver.find_element(By.ID, "blocking-pause")
non_blocking_pause_button = driver.find_element(By.ID, "non-blocking-pause")
driver.find_element(By.ID, "reset")
# get a reference to the counter
counter = driver.find_element(By.ID, "counter")
# get a reference to the iterations input
iterations_input = driver.find_element(By.ID, "iterations")
# kick off background tasks
iterations_input.clear()
iterations_input.send_keys("50")
delayed_increment_button.click()
blocking_pause_button.click()
delayed_increment_button.click()
for _ in range(10):
increment_button.click()
blocking_pause_button.click()
delayed_increment_button.click()
delayed_increment_button.click()
yield_increment_button.click()
non_blocking_pause_button.click()
yield_increment_button.click()
blocking_pause_button.click()
yield_increment_button.click()
for _ in range(10):
increment_button.click()
yield_increment_button.click()
blocking_pause_button.click()
assert background_task._poll_for(lambda: counter.text == "420", timeout=40)
# all tasks should have exited and cleaned up
assert background_task._poll_for(
lambda: not background_task.app_instance.background_tasks # type: ignore
)

View File

@ -1,107 +0,0 @@
"""Test that per-component state scaffold works and operates independently."""
from typing import Generator
import pytest
from selenium.webdriver.common.by import By
from reflex.testing import AppHarness
from . import utils
def ComponentStateApp():
"""App using per component state."""
import reflex as rx
class MultiCounter(rx.ComponentState):
count: int = 0
def increment(self):
self.count += 1
@classmethod
def get_component(cls, *children, **props):
return rx.vstack(
*children,
rx.heading(cls.count, id=f"count-{props.get('id', 'default')}"),
rx.button(
"Increment",
on_click=cls.increment,
id=f"button-{props.get('id', 'default')}",
),
**props,
)
app = rx.App(state=rx.State) # noqa
@rx.page()
def index():
mc_a = MultiCounter.create(id="a")
mc_b = MultiCounter.create(id="b")
assert mc_a.State != mc_b.State
return rx.vstack(
mc_a,
mc_b,
rx.button(
"Inc A",
on_click=mc_a.State.increment, # type: ignore
id="inc-a",
),
)
@pytest.fixture()
def component_state_app(tmp_path) -> Generator[AppHarness, None, None]:
"""Start ComponentStateApp app at tmp_path via AppHarness.
Args:
tmp_path: pytest tmp_path fixture
Yields:
running AppHarness instance
"""
with AppHarness.create(
root=tmp_path,
app_source=ComponentStateApp, # type: ignore
) as harness:
yield harness
@pytest.mark.asyncio
async def test_component_state_app(component_state_app: AppHarness):
"""Increment counters independently.
Args:
component_state_app: harness for ComponentStateApp app
"""
assert component_state_app.app_instance is not None, "app is not running"
driver = component_state_app.frontend()
ss = utils.SessionStorage(driver)
token = AppHarness._poll_for(lambda: ss.get("token") is not None)
assert token is not None
count_a = driver.find_element(By.ID, "count-a")
count_b = driver.find_element(By.ID, "count-b")
button_a = driver.find_element(By.ID, "button-a")
button_b = driver.find_element(By.ID, "button-b")
button_inc_a = driver.find_element(By.ID, "inc-a")
assert count_a.text == "0"
button_a.click()
assert component_state_app.poll_for_content(count_a, exp_not_equal="0") == "1"
button_a.click()
assert component_state_app.poll_for_content(count_a, exp_not_equal="1") == "2"
button_inc_a.click()
assert component_state_app.poll_for_content(count_a, exp_not_equal="2") == "3"
assert count_b.text == "0"
button_b.click()
assert component_state_app.poll_for_content(count_b, exp_not_equal="0") == "1"
button_b.click()
assert component_state_app.poll_for_content(count_b, exp_not_equal="1") == "2"

View File

@ -1,89 +0,0 @@
"""Test case for displaying the connection banner when the websocket drops."""
from typing import Generator
import pytest
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from reflex.testing import AppHarness, WebDriver
def ConnectionBanner():
"""App with a connection banner."""
import reflex as rx
class State(rx.State):
foo: int = 0
def index():
return rx.text("Hello World")
app = rx.App(state=rx.State)
app.add_page(index)
@pytest.fixture()
def connection_banner(tmp_path) -> Generator[AppHarness, None, None]:
"""Start ConnectionBanner app at tmp_path via AppHarness.
Args:
tmp_path: pytest tmp_path fixture
Yields:
running AppHarness instance
"""
with AppHarness.create(
root=tmp_path,
app_source=ConnectionBanner, # type: ignore
) as harness:
yield harness
CONNECTION_ERROR_XPATH = "//*[ text() = 'Connection Error' ]"
def has_error_modal(driver: WebDriver) -> bool:
"""Check if the connection error modal is displayed.
Args:
driver: Selenium webdriver instance.
Returns:
True if the modal is displayed, False otherwise.
"""
try:
driver.find_element(By.XPATH, CONNECTION_ERROR_XPATH)
return True
except NoSuchElementException:
return False
def test_connection_banner(connection_banner: AppHarness):
"""Test that the connection banner is displayed when the websocket drops.
Args:
connection_banner: AppHarness instance.
"""
assert connection_banner.app_instance is not None
assert connection_banner.backend is not None
driver = connection_banner.frontend()
connection_banner._poll_for(lambda: not has_error_modal(driver))
# Get the backend port
backend_port = connection_banner._poll_for_servers().getsockname()[1]
# Kill the backend
connection_banner.backend.should_exit = True
if connection_banner.backend_thread is not None:
connection_banner.backend_thread.join()
# Error modal should now be displayed
connection_banner._poll_for(lambda: has_error_modal(driver))
# Bring the backend back up
connection_banner._start_backend(port=backend_port)
# Banner should be gone now
connection_banner._poll_for(lambda: not has_error_modal(driver))

View File

@ -1,170 +0,0 @@
"""Integration tests for table and related components."""
from typing import Generator
import pytest
from selenium.webdriver.common.by import By
from reflex.testing import AppHarness
def Table():
"""App using table component."""
from typing import List
import reflex as rx
class TableState(rx.State):
rows: List[List[str]] = [
["John", "30", "New York"],
["Jane", "31", "San Fransisco"],
["Joe", "32", "Los Angeles"],
]
headers: List[str] = ["Name", "Age", "Location"]
footers: List[str] = ["footer1", "footer2", "footer3"]
caption: str = "random caption"
app = rx.App(state=rx.State)
@app.add_page
def index():
return rx.center(
rx.chakra.input(
id="token",
value=TableState.router.session.client_token,
is_read_only=True,
),
rx.chakra.table_container(
rx.chakra.table(
headers=TableState.headers,
rows=TableState.rows,
footers=TableState.footers,
caption=TableState.caption,
variant="striped",
color_scheme="blue",
width="100%",
),
),
)
@app.add_page
def another():
return rx.center(
rx.chakra.table_container(
rx.chakra.table( # type: ignore
rx.chakra.thead( # type: ignore
rx.chakra.tr( # type: ignore
rx.chakra.th("Name"),
rx.chakra.th("Age"),
rx.chakra.th("Location"),
)
),
rx.chakra.tbody( # type: ignore
rx.chakra.tr( # type: ignore
rx.chakra.td("John"),
rx.chakra.td(30),
rx.chakra.td("New York"),
),
rx.chakra.tr( # type: ignore
rx.chakra.td("Jane"),
rx.chakra.td(31),
rx.chakra.td("San Francisco"),
),
rx.chakra.tr( # type: ignore
rx.chakra.td("Joe"),
rx.chakra.td(32),
rx.chakra.td("Los Angeles"),
),
),
rx.chakra.tfoot( # type: ignore
rx.chakra.tr(
rx.chakra.td("footer1"),
rx.chakra.td("footer2"),
rx.chakra.td("footer3"),
) # type: ignore
),
rx.chakra.table_caption("random caption"),
variant="striped",
color_scheme="teal",
)
)
)
@pytest.fixture()
def table(tmp_path_factory) -> Generator[AppHarness, None, None]:
"""Start Table app at tmp_path via AppHarness.
Args:
tmp_path_factory: pytest tmp_path_factory fixture
Yields:
running AppHarness instance
"""
with AppHarness.create(
root=tmp_path_factory.mktemp("table"),
app_source=Table, # type: ignore
) as harness:
assert harness.app_instance is not None, "app is not running"
yield harness
@pytest.fixture
def driver(table: AppHarness):
"""GEt an instance of the browser open to the table app.
Args:
table: harness for Table app
Yields:
WebDriver instance.
"""
driver = table.frontend()
try:
token_input = driver.find_element(By.ID, "token")
assert token_input
# wait for the backend connection to send the token
token = table.poll_for_value(token_input)
assert token is not None
yield driver
finally:
driver.quit()
@pytest.mark.parametrize("route", ["", "/another"])
def test_table(driver, table: AppHarness, route):
"""Test that a table component is rendered properly.
Args:
driver: Selenium WebDriver open to the app
table: Harness for Table app
route: Page route or path.
"""
driver.get(f"{table.frontend_url}/{route}")
assert table.app_instance is not None, "app is not running"
thead = driver.find_element(By.TAG_NAME, "thead")
# poll till page is fully loaded.
table.poll_for_content(element=thead)
# check headers
assert thead.find_element(By.TAG_NAME, "tr").text == "NAME AGE LOCATION"
# check first row value
assert (
driver.find_element(By.TAG_NAME, "tbody")
.find_elements(By.TAG_NAME, "tr")[0]
.text
== "John 30 New York"
)
# check footer
assert (
driver.find_element(By.TAG_NAME, "tfoot")
.find_element(By.TAG_NAME, "tr")
.text.lower()
== "footer1 footer2 footer3"
)
# check caption
assert driver.find_element(By.TAG_NAME, "caption").text == "random caption"

View File

@ -1,67 +0,0 @@
"""Integration tests for all urls in Reflex."""
import os
import re
from pathlib import Path
import pytest
import requests
def check_urls(repo_dir):
"""Check that all URLs in the repo are valid and secure.
Args:
repo_dir: The directory of the repo.
Returns:
A list of errors.
"""
url_pattern = re.compile(r'http[s]?://reflex\.dev[^\s")]*')
errors = []
for root, _dirs, files in os.walk(repo_dir):
if "__pycache__" in root:
continue
for file_name in files:
if not file_name.endswith(".py") and not file_name.endswith(".md"):
continue
file_path = os.path.join(root, file_name)
try:
with open(file_path, "r", encoding="utf-8", errors="ignore") as file:
for line in file:
urls = url_pattern.findall(line)
for url in set(urls):
if url.startswith("http://"):
errors.append(
f"Found insecure HTTP URL: {url} in {file_path}"
)
url = url.strip('"\n')
try:
response = requests.head(
url, allow_redirects=True, timeout=5
)
response.raise_for_status()
except requests.RequestException as e:
errors.append(
f"Error accessing URL: {url} in {file_path} | Error: {e}, , Check your path ends with a /"
)
except Exception as e:
errors.append(f"Error reading file: {file_path} | Error: {e}")
return errors
@pytest.mark.parametrize(
"repo_dir",
[Path(__file__).resolve().parent.parent / "reflex"],
)
def test_find_and_check_urls(repo_dir):
"""Test that all URLs in the repo are valid and secure.
Args:
repo_dir: The directory of the repo.
"""
errors = check_urls(repo_dir)
assert not errors, "\n".join(errors)

3314
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,91 +1,74 @@
[tool.poetry]
name = "reflex"
version = "0.5.0"
version = "0.7.2dev1"
description = "Web apps in pure Python."
license = "Apache-2.0"
authors = [
"Nikhil Rao <nikhil@reflex.dev>",
"Alek Petuskey <alek@reflex.dev>",
"Masen Furer <masen@reflex.dev>",
"Elijah Ahianyo <elijah@reflex.dev>",
"Thomas Brandého <thomas@reflex.dev>",
"Nikhil Rao <nikhil@reflex.dev>",
"Alek Petuskey <alek@reflex.dev>",
"Masen Furer <masen@reflex.dev>",
"Elijah Ahianyo <elijah@reflex.dev>",
"Thomas Brandého <thomas@reflex.dev>",
]
readme = "README.md"
homepage = "https://reflex.dev"
repository = "https://github.com/reflex-dev/reflex"
documentation = "https://reflex.dev/docs/getting-started/introduction"
keywords = [
"web",
"framework",
]
classifiers = [
"Development Status :: 4 - Beta",
]
packages = [
{include = "reflex"}
]
keywords = ["web", "framework"]
classifiers = ["Development Status :: 4 - Beta"]
[tool.poetry.dependencies]
python = "^3.8"
dill = ">=0.3.8,<0.4"
fastapi = ">=0.96.0,<1.0"
gunicorn = ">=20.1.0,<23.0"
python = ">=3.10, <4.0"
fastapi = ">=0.96.0,!=0.111.0,!=0.111.1"
gunicorn = ">=20.1.0,<24.0"
jinja2 = ">=3.1.2,<4.0"
psutil = ">=5.9.4,<6.0"
pydantic = ">=1.10.2,<3.0"
psutil = ">=5.9.4,<7.0"
pydantic = ">=1.10.21,<3.0"
python-multipart = ">=0.0.5,<0.1"
python-socketio = ">=5.7.0,<6.0"
redis = ">=4.3.5,<6.0"
rich = ">=13.0.0,<14.0"
sqlmodel = ">=0.0.14,<0.1"
typer = ">=0.4.2,<1.0"
uvicorn = [
{version = "^0.24.0", python = ">=3.12"},
{version = "^0.20.0", python = "<3.12"},
]
watchdog = ">=2.3.1,<5.0"
watchfiles = ">=0.19.0,<1.0"
typer = ">=0.15.1,<1.0"
uvicorn = ">=0.20.0"
starlette-admin = ">=0.11.0,<1.0"
alembic = ">=1.11.1,<2.0"
platformdirs = ">=3.10.0,<5.0"
distro = {version = ">=1.8.0,<2.0", platform = "linux"}
distro = { version = ">=1.8.0,<2.0", platform = "linux" }
python-engineio = "!=4.6.0"
wrapt = [
{version = ">=1.14.0,<2.0", python = ">=3.11"},
{version = ">=1.11.0,<2.0", python = "<3.11"},
]
wrapt = ">=1.17.0,<2.0"
packaging = ">=23.1,<25.0"
reflex-hosting-cli = ">=0.1.2,<2.0"
reflex-hosting-cli = ">=0.1.29"
charset-normalizer = ">=3.3.2,<4.0"
wheel = ">=0.42.0,<1.0"
build = ">=1.0.3,<2.0"
setuptools = ">=69.1.1,<70.0"
setuptools = ">=75.0"
httpx = ">=0.25.1,<1.0"
twine = ">=4.0.0,<6.0"
twine = ">=4.0.0,<7.0"
tomlkit = ">=0.12.4,<1.0"
lazy_loader = ">=0.4"
typing_extensions = ">=4.6.0"
[tool.poetry.group.dev.dependencies]
pytest = ">=7.1.2,<8.0"
pytest = ">=7.1.2,<9.0"
pytest-mock = ">=3.10.0,<4.0"
pyright = ">=1.1.229,<1.1.335"
pyright = ">=1.1.394, <1.2"
darglint = ">=1.8.1,<2.0"
dill = ">=0.3.8"
toml = ">=0.10.2,<1.0"
pytest-asyncio = ">=0.20.1,<0.22.0" # https://github.com/pytest-dev/pytest-asyncio/issues/706
pytest-cov = ">=4.0.0,<5.0"
black = "^22.10.0,<23.0"
ruff = "0.1.0"
pandas = [
{version = ">=2.1.1,<3.0", python = ">=3.9,<3.13"},
{version = ">=1.5.3,<2.0", python = ">=3.8,<3.9"},
]
pillow = [
{version = ">=10.0.0,<11.0", python = ">=3.8,<4.0"}
]
pytest-asyncio = ">=0.24.0"
pytest-cov = ">=4.0.0,<7.0"
ruff = "0.9.6"
pandas = ">=2.1.1,<3.0"
pillow = ">=10.0.0,<12.0"
plotly = ">=5.13.0,<6.0"
asynctest = ">=0.13.0,<1.0"
pre-commit = {version = ">=3.2.1", python = ">=3.8,<4.0"}
pre-commit = ">=3.2.1"
selenium = ">=4.11.0,<5.0"
pytest-benchmark = ">=4.0.0,<5.0"
pytest-benchmark = ">=4.0.0,<6.0"
playwright = ">=1.46.0"
pytest-playwright = ">=0.5.1"
pytest-codspeed = "^3.1.2"
[tool.poetry.scripts]
reflex = "reflex.reflex:cli"
@ -95,15 +78,60 @@ requires = ["poetry-core>=1.5.1"]
build-backend = "poetry.core.masonry.api"
[tool.pyright]
reportIncompatibleMethodOverride = false
[tool.ruff]
exclude = ["*.pyi"]
target-version = "py37"
lint.select = ["B", "D", "E", "F", "I", "SIM", "W"]
lint.ignore = ["B008", "D203", "D205", "D213", "D401", "D406", "D407", "E501", "F403", "F405", "F541"]
target-version = "py310"
output-format = "concise"
lint.isort.split-on-trailing-comma = false
lint.select = [
"ANN001",
"B",
"C4",
"D",
"E",
"ERA",
"F",
"FURB",
"I",
"N",
"PERF",
"PGH",
"PTH",
"RUF",
"SIM",
"T",
"TRY",
"W",
]
lint.ignore = [
"B008",
"D205",
"E501",
"F403",
"SIM115",
"RUF006",
"RUF008",
"RUF012",
"TRY0",
]
lint.pydocstyle.convention = "google"
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
"tests/*.py" = ["D100", "D103", "D104", "B018"]
"tests/*.py" = ["ANN001", "D100", "D103", "D104", "B018", "PERF", "T", "N"]
"benchmarks/*.py" = ["ANN001", "D100", "D103", "D104", "B018", "PERF", "T", "N"]
"reflex/.templates/*.py" = ["D100", "D103", "D104"]
"*.pyi" = ["ALL"]
"*.pyi" = ["D301", "D415", "D417", "D418", "E742", "N", "PGH"]
"pyi_generator.py" = ["N802"]
"reflex/constants/*.py" = ["N"]
"*/blank.py" = ["I001"]
[tool.pytest.ini_options]
filterwarnings = "ignore:fields may not start with an underscore:RuntimeWarning"
asyncio_default_fixture_loop_scope = "function"
asyncio_mode = "auto"
[tool.codespell]
skip = "docs/*,*.html,examples/*, *.pyi, poetry.lock"
ignore-words-list = "te, TreeE"

View File

@ -1,4 +0,0 @@
*.db
*.py[cod]
.web
__pycache__/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,10 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Github" clip-path="url(#clip0_469_1929)">
<path id="Vector" d="M8.0004 0.587524C3.80139 0.587524 0.400391 3.98851 0.400391 8.1875C0.400391 11.5505 2.57589 14.391 5.59689 15.398C5.97689 15.4645 6.11939 15.2365 6.11939 15.037C6.11939 14.8565 6.10989 14.258 6.10989 13.6215C4.20039 13.973 3.70639 13.156 3.55439 12.7285C3.46889 12.51 3.09839 11.8355 2.77539 11.655C2.50939 11.5125 2.12939 11.161 2.76589 11.1515C3.36439 11.142 3.79189 11.7025 3.93439 11.9305C4.61839 13.08 5.71089 12.757 6.14789 12.5575C6.21439 12.0635 6.41388 11.731 6.6324 11.541C4.94139 11.351 3.17439 10.6955 3.17439 7.7885C3.17439 6.962 3.46889 6.27801 3.95339 5.74601C3.87739 5.55601 3.61139 4.77701 4.02939 3.73201C4.02939 3.73201 4.66589 3.53251 6.11939 4.51101C6.7274 4.34001 7.3734 4.25451 8.0194 4.25451C8.6654 4.25451 9.3114 4.34001 9.9194 4.51101C11.3729 3.52301 12.0094 3.73201 12.0094 3.73201C12.4274 4.77701 12.1614 5.55601 12.0854 5.74601C12.5699 6.27801 12.8644 6.9525 12.8644 7.7885C12.8644 10.705 11.0879 11.351 9.3969 11.541C9.6724 11.7785 9.9099 12.2345 9.9099 12.947C9.9099 13.9635 9.9004 14.7805 9.9004 15.037C9.9004 15.2365 10.0429 15.474 10.4229 15.398C13.5165 14.3536 15.5996 11.4527 15.6004 8.1875C15.6004 3.98851 12.1994 0.587524 8.0004 0.587524Z" fill="#494369"/>
</g>
<defs>
<clipPath id="clip0_469_1929">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,37 +0,0 @@
<svg width="67" height="14" viewBox="0 0 67 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="67" height="14" fill="#1E1E1E"/>
<g id="Nav Template &#62; Initial" clip-path="url(#clip0_0_1)">
<rect width="1440" height="1024" transform="translate(-16 -17)" fill="white"/>
<g id="Sidebar">
<g clip-path="url(#clip1_0_1)">
<path d="M-16 -17H264V1007H-16V-17Z" fill="white"/>
<g id="Header">
<path d="M-16 -17H264V31H-16V-17Z" fill="white"/>
<g id="Button">
<rect x="-4" y="-3" width="74.316" height="20" rx="6" fill="white"/>
<g id="Logo">
<g id="Reflex">
<path d="M0 13.6316V0.368408H10.6106V5.67369H7.95792V3.02105H2.65264V5.67369H7.95792V8.32633H2.65264V13.6316H0ZM7.95792 13.6316V8.32633H10.6106V13.6316H7.95792Z" fill="#110F1F"/>
<path d="M13.2632 13.6316V0.368408H21.2211V3.02105H15.9158V5.67369H21.2211V8.32633H15.9158V10.979H21.2211V13.6316H13.2632Z" fill="#110F1F"/>
<path d="M23.8738 13.6316V0.368408H31.8317V3.02105H26.5264V5.67369H31.8317V8.32633H26.5264V13.6316H23.8738Z" fill="#110F1F"/>
<path d="M34.4843 13.6316V0.368408H37.137V10.979H42.4422V13.6316H34.4843Z" fill="#110F1F"/>
<path d="M45.0949 13.6316V0.368408H53.0528V3.02105H47.7475V5.67369H53.0528V8.32633H47.7475V10.979H53.0528V13.6316H45.0949Z" fill="#110F1F"/>
<path d="M55.7054 5.67369V0.368408H58.3581V5.67369H55.7054ZM63.6634 5.67369V0.368408H66.316V5.67369H63.6634ZM58.3581 8.32633V5.67369H63.6634V8.32633H58.3581ZM55.7054 13.6316V8.32633H58.3581V13.6316H55.7054ZM63.6634 13.6316V8.32633H66.316V13.6316H63.6634Z" fill="#110F1F"/>
</g>
</g>
</g>
<path d="M264 30.5H-16V31.5H264V30.5Z" fill="#F4F3F6"/>
</g>
</g>
<path d="M263.5 -17V1007H264.5V-17H263.5Z" fill="#F4F3F6"/>
</g>
</g>
<defs>
<clipPath id="clip0_0_1">
<rect width="1440" height="1024" fill="white" transform="translate(-16 -17)"/>
</clipPath>
<clipPath id="clip1_0_1">
<path d="M-16 -17H264V1007H-16V-17Z" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,68 +0,0 @@
<svg width="80" height="78" viewBox="0 0 80 78" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_ddddi_449_2821)">
<path d="M13 11C13 6.58172 16.5817 3 21 3H59C63.4183 3 67 6.58172 67 11V49C67 52.3137 64.3137 55 61 55H19C15.6863 55 13 52.3137 13 49V11Z" fill="url(#paint0_radial_449_2821)"/>
<path d="M13 11C13 6.58172 16.5817 3 21 3H59C63.4183 3 67 6.58172 67 11V49C67 52.3137 64.3137 55 61 55H19C15.6863 55 13 52.3137 13 49V11Z" fill="url(#paint1_radial_449_2821)"/>
<g filter="url(#filter1_i_449_2821)">
<path d="M31 37.5C30.4477 37.5 30 37.0523 30 36.5V13.5001C30 12.9478 30.4477 12.5001 31 12.5001H49C49.5523 12.5001 50 12.9478 50 13.5001V21.5001C50 22.0524 49.5523 22.5001 49 22.5001H45V18.5001C45 17.9478 44.5523 17.5001 44 17.5001H36C35.4477 17.5001 35 17.9478 35 18.5001V21.5001C35 22.0524 35.4477 22.5001 36 22.5001H45V27.5001H36C35.4477 27.5001 35 27.9478 35 28.5001V36.5C35 37.0523 34.5523 37.5 34 37.5H31ZM46 37.5C45.4477 37.5 45 37.0523 45 36.5V27.5001H49C49.5523 27.5001 50 27.9478 50 28.5001V36.5C50 37.0523 49.5523 37.5 49 37.5H46Z" fill="url(#paint2_radial_449_2821)"/>
</g>
<path d="M13 11C13 6.58172 16.5817 3 21 3H59C63.4183 3 67 6.58172 67 11V49C67 52.3137 64.3137 55 61 55H19C15.6863 55 13 52.3137 13 49V11Z" stroke="#20117E" stroke-opacity="0.04"/>
</g>
<defs>
<filter id="filter0_ddddi_449_2821" x="0.5" y="0.5" width="79" height="77" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feMorphology radius="4" operator="erode" in="SourceAlpha" result="effect1_dropShadow_449_2821"/>
<feOffset dy="10"/>
<feGaussianBlur stdDeviation="8"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0784314 0 0 0 0 0.0705882 0 0 0 0 0.231373 0 0 0 0.06 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_449_2821"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feMorphology radius="6" operator="erode" in="SourceAlpha" result="effect2_dropShadow_449_2821"/>
<feOffset dy="12"/>
<feGaussianBlur stdDeviation="3"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0784314 0 0 0 0 0.0705882 0 0 0 0 0.231373 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_449_2821" result="effect2_dropShadow_449_2821"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feMorphology radius="4" operator="erode" in="SourceAlpha" result="effect3_dropShadow_449_2821"/>
<feOffset dy="10"/>
<feGaussianBlur stdDeviation="3"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.12549 0 0 0 0 0.0666667 0 0 0 0 0.494118 0 0 0 0.16 0"/>
<feBlend mode="normal" in2="effect2_dropShadow_449_2821" result="effect3_dropShadow_449_2821"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feMorphology radius="1" operator="dilate" in="SourceAlpha" result="effect4_dropShadow_449_2821"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.12549 0 0 0 0 0.0666667 0 0 0 0 0.494118 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="effect3_dropShadow_449_2821" result="effect4_dropShadow_449_2821"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect4_dropShadow_449_2821" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-8"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.678431 0 0 0 0 0.607843 0 0 0 0 0.972549 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="shape" result="effect5_innerShadow_449_2821"/>
</filter>
<filter id="filter1_i_449_2821" x="30" y="12.5001" width="20" height="26.9999" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="1.5"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.12549 0 0 0 0 0.0666667 0 0 0 0 0.494118 0 0 0 0.32 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_449_2821"/>
</filter>
<radialGradient id="paint0_radial_449_2821" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(40 3) rotate(90) scale(52 54)">
<stop stop-color="white" stop-opacity="0.9"/>
<stop offset="1" stop-color="#4E3DB9" stop-opacity="0.24"/>
</radialGradient>
<radialGradient id="paint1_radial_449_2821" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(40 3) rotate(90) scale(52 54)">
<stop stop-color="white"/>
<stop offset="1" stop-color="#F7F7F7"/>
</radialGradient>
<radialGradient id="paint2_radial_449_2821" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(40 12.5001) rotate(90) scale(24.9999 20)">
<stop stop-color="#F5F3FF"/>
<stop stop-color="white"/>
<stop offset="1" stop-color="#E1DDF4"/>
</radialGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -1,13 +0,0 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="PaneLeft" clip-path="url(#clip0_469_1942)">
<g id="Vector">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.80217 0.525009C7.34654 0.525009 6.97717 0.894373 6.97717 1.35001V10.65C6.97717 11.1056 7.34654 11.475 7.80217 11.475H10.6522C11.1078 11.475 11.4772 11.1056 11.4772 10.65V1.35001C11.4772 0.894373 11.1078 0.525009 10.6522 0.525009H7.80217ZM8.02717 10.425V1.57501H10.4272V10.425H8.02717Z" fill="#494369"/>
<path d="M3.78215 8.14502L2.16213 6.525H5.92717V5.475H2.16213L3.78215 3.85498L3.03969 3.11252L0.523438 5.62877V6.37123L3.03969 8.88748L3.78215 8.14502Z" fill="#494369"/>
</g>
</g>
<defs>
<clipPath id="clip0_469_1942">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 807 B

View File

@ -1 +0,0 @@
"""Base template for Reflex."""

View File

@ -1,126 +0,0 @@
"""Welcome to Reflex! This file outlines the steps to create a basic app."""
from typing import Callable
import reflex as rx
from .pages import chatapp_page, datatable_page, forms_page, graphing_page, home_page
from .sidebar import sidebar
from .state import State
from .styles import *
meta = [
{
"name": "viewport",
"content": "width=device-width, shrink-to-fit=no, initial-scale=1",
},
]
def template(main_content: Callable[[], rx.Component]) -> rx.Component:
"""The template for each page of the app.
Args:
main_content (Callable[[], rx.Component]): The main content of the page.
Returns:
rx.Component: The template for each page of the app.
"""
menu_button = rx.chakra.box(
rx.chakra.menu(
rx.chakra.menu_button(
rx.chakra.icon(
tag="hamburger",
size="4em",
color=text_color,
),
),
rx.chakra.menu_list(
rx.chakra.menu_item(rx.chakra.link("Home", href="/", width="100%")),
rx.chakra.menu_divider(),
rx.chakra.menu_item(
rx.chakra.link(
"About", href="https://github.com/reflex-dev", width="100%"
)
),
rx.chakra.menu_item(
rx.chakra.link(
"Contact", href="mailto:founders@reflex.dev", width="100%"
)
),
),
),
position="fixed",
right="1.5em",
top="1.5em",
z_index="500",
)
return rx.chakra.hstack(
sidebar(),
main_content(),
rx.chakra.spacer(),
menu_button,
align_items="flex-start",
transition="left 0.5s, width 0.5s",
position="relative",
left=rx.cond(State.sidebar_displayed, "0px", f"-{sidebar_width}"),
)
@rx.page("/", meta=meta)
@template
def home() -> rx.Component:
"""Home page.
Returns:
rx.Component: The home page.
"""
return home_page()
@rx.page("/forms", meta=meta)
@template
def forms() -> rx.Component:
"""Forms page.
Returns:
rx.Component: The settings page.
"""
return forms_page()
@rx.page("/graphing", meta=meta)
@template
def graphing() -> rx.Component:
"""Graphing page.
Returns:
rx.Component: The graphing page.
"""
return graphing_page()
@rx.page("/datatable", meta=meta)
@template
def datatable() -> rx.Component:
"""Data Table page.
Returns:
rx.Component: The chatapp page.
"""
return datatable_page()
@rx.page("/chatapp", meta=meta)
@template
def chatapp() -> rx.Component:
"""Chatapp page.
Returns:
rx.Component: The chatapp page.
"""
return chatapp_page()
# Create the app.
app = rx.App(style=base_style)

View File

@ -1,6 +0,0 @@
"""The pages of the app."""
from .chatapp import chatapp_page
from .datatable import datatable_page
from .forms import forms_page
from .graphing import graphing_page
from .home import home_page

View File

@ -1,31 +0,0 @@
"""The main Chat app."""
import reflex as rx
from ..styles import *
from ..webui import styles
from ..webui.components import chat, modal, navbar, sidebar
def chatapp_page() -> rx.Component:
"""The main app.
Returns:
The UI for the main app.
"""
return rx.chakra.box(
rx.chakra.vstack(
navbar(),
chat.chat(),
chat.action_bar(),
sidebar(),
modal(),
bg=styles.bg_dark_color,
color=styles.text_light_color,
min_h="100vh",
align_items="stretch",
spacing="0",
style=template_content_style,
),
style=template_page_style,
)

View File

@ -1,359 +0,0 @@
"""The settings page for the template."""
from typing import Any
import reflex as rx
from reflex.components.datadisplay.dataeditor import DataEditorTheme
from ..styles import *
from ..webui.state import State
class DataTableState(State):
"""Datatable state."""
cols: list[Any] = [
{"title": "Title", "type": "str"},
{
"title": "Name",
"type": "str",
"group": "Data",
"width": 300,
},
{
"title": "Birth",
"type": "str",
"group": "Data",
"width": 150,
},
{
"title": "Human",
"type": "bool",
"group": "Data",
"width": 80,
},
{
"title": "House",
"type": "str",
"group": "Data",
},
{
"title": "Wand",
"type": "str",
"group": "Data",
"width": 250,
},
{
"title": "Patronus",
"type": "str",
"group": "Data",
},
{
"title": "Blood status",
"type": "str",
"group": "Data",
"width": 200,
},
]
data = [
[
"1",
"Harry James Potter",
"31 July 1980",
True,
"Gryffindor",
"11' Holly phoenix feather",
"Stag",
"Half-blood",
],
[
"2",
"Ronald Bilius Weasley",
"1 March 1980",
True,
"Gryffindor",
"12' Ash unicorn tail hair",
"Jack Russell terrier",
"Pure-blood",
],
[
"3",
"Hermione Jean Granger",
"19 September, 1979",
True,
"Gryffindor",
"10¾' vine wood dragon heartstring",
"Otter",
"Muggle-born",
],
[
"4",
"Albus Percival Wulfric Brian Dumbledore",
"Late August 1881",
True,
"Gryffindor",
"15' Elder Thestral tail hair core",
"Phoenix",
"Half-blood",
],
[
"5",
"Rubeus Hagrid",
"6 December 1928",
False,
"Gryffindor",
"16' Oak unknown core",
"None",
"Part-Human (Half-giant)",
],
[
"6",
"Fred Weasley",
"1 April, 1978",
True,
"Gryffindor",
"Unknown",
"Unknown",
"Pure-blood",
],
[
"7",
"George Weasley",
"1 April, 1978",
True,
"Gryffindor",
"Unknown",
"Unknown",
"Pure-blood",
],
]
code_show = """rx.chakra.hstack(
rx.chakra.divider(orientation="vertical", height="100vh", border="solid black 1px"),
rx.chakra.vstack(
rx.chakra.box(
rx.data_editor(
columns=DataTableState.cols,
data=DataTableState.data,
draw_focus_ring=True,
row_height=50,
smooth_scroll_x=True,
smooth_scroll_y=True,
column_select="single",
# style
theme=DataEditorTheme(**darkTheme),
width="80vw",
height="80vh",
),
),
rx.chakra.spacer(),
height="100vh",
spacing="25",
),
)"""
state_show = """class DataTableState(State):
cols: list[Any] = [
{"title": "Title", "type": "str"},
{
"title": "Name",
"type": "str",
"group": "Data",
"width": 300,
},
{
"title": "Birth",
"type": "str",
"group": "Data",
"width": 150,
},
{
"title": "Human",
"type": "bool",
"group": "Data",
"width": 80,
},
{
"title": "House",
"type": "str",
"group": "Data",
},
{
"title": "Wand",
"type": "str",
"group": "Data",
"width": 250,
},
{
"title": "Patronus",
"type": "str",
"group": "Data",
},
{
"title": "Blood status",
"type": "str",
"group": "Data",
"width": 200,
},
]"""
data_show = """[
["1", "Harry James Potter", "31 July 1980", True, "Gryffindor", "11' Holly phoenix feather", "Stag", "Half-blood"],
["2", "Ronald Bilius Weasley", "1 March 1980", True,"Gryffindor", "12' Ash unicorn tail hair", "Jack Russell terrier", "Pure-blood"],
["3", "Hermione Jean Granger", "19 September, 1979", True, "Gryffindor", "10¾' vine wood dragon heartstring", "Otter", "Muggle-born"],
["4", "Albus Percival Wulfric Brian Dumbledore", "Late August 1881", True, "Gryffindor", "15' Elder Thestral tail hair core", "Phoenix", "Half-blood"],
["5", "Rubeus Hagrid", "6 December 1928", False, "Gryffindor", "16' Oak unknown core", "None", "Part-Human (Half-giant)"],
["6", "Fred Weasley", "1 April, 1978", True, "Gryffindor", "Unknown", "Unknown", "Pure-blood"],
["7", "George Weasley", "1 April, 1978", True, "Gryffindor", "Unknown", "Unknown", "Pure-blood"],
]"""
darkTheme = {
"accent_color": "#8c96ff",
"accent_light": "rgba(202, 206, 255, 0.253)",
"text_dark": "#ffffff",
"text_medium": "#b8b8b8",
"text_light": "#a0a0a0",
"text_bubble": "#ffffff",
"bg_icon_header": "#b8b8b8",
"fg_icon_header": "#000000",
"text_header": "#a1a1a1",
"text_header_selected": "#000000",
"bg_cell": "#16161b",
"bg_cell_medium": "#202027",
"bg_header": "#212121",
"bg_header_has_focus": "#474747",
"bg_header_hovered": "#404040",
"bg_bubble": "#212121",
"bg_bubble_selected": "#000000",
"bg_search_result": "#423c24",
"border_color": "rgba(225,225,225,0.2)",
"drilldown_border": "rgba(225,225,225,0.4)",
"link_color": "#4F5DFF",
"header_font_style": "bold 14px",
"base_font_style": "13px",
"font_family": "Inter, Roboto, -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Ubuntu, noto, arial, sans-serif",
}
darkTheme_show = """darkTheme={
"accent_color": "#8c96ff",
"accent_light": "rgba(202, 206, 255, 0.253)",
"text_dark": "#ffffff",
"text_medium": "#b8b8b8",
"text_light": "#a0a0a0",
"text_bubble": "#ffffff",
"bg_icon_header": "#b8b8b8",
"fg_icon_header": "#000000",
"text_header": "#a1a1a1",
"text_header_selected": "#000000",
"bg_cell": "#16161b",
"bg_cell_medium": "#202027",
"bg_header": "#212121",
"bg_header_has_focus": "#474747",
"bg_header_hovered": "#404040",
"bg_bubble": "#212121",
"bg_bubble_selected": "#000000",
"bg_search_result": "#423c24",
"border_color": "rgba(225,225,225,0.2)",
"drilldown_border": "rgba(225,225,225,0.4)",
"link_color": "#4F5DFF",
"header_font_style": "bold 14px",
"base_font_style": "13px",
"font_family": "Inter, Roboto, -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Ubuntu, noto, arial, sans-serif",
}"""
def datatable_page() -> rx.Component:
"""The UI for the settings page.
Returns:
rx.Component: The UI for the settings page.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.heading(
"Data Table Demo",
font_size="3em",
),
rx.chakra.hstack(
rx.chakra.vstack(
rx.chakra.box(
rx.data_editor(
columns=DataTableState.cols,
data=DataTableState.data,
draw_focus_ring=True,
row_height=50,
smooth_scroll_x=True,
smooth_scroll_y=True,
column_select="single",
# style
theme=DataEditorTheme(**darkTheme),
width="80vw",
),
),
rx.chakra.spacer(),
spacing="25",
),
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("Data", style=tab_style),
rx.chakra.tab("State", style=tab_style),
rx.chakra.tab("Styling", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
code_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
data_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
state_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
darkTheme_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
style=template_content_style,
),
style=template_page_style,
)

View File

@ -1,256 +0,0 @@
"""The settings page for the template."""
import reflex as rx
from ..states.form_state import FormState, UploadState
from ..styles import *
forms_1_code = """rx.chakra.vstack(
rx.chakra.form(
rx.chakra.vstack(
rx.chakra.input(
placeholder="First Name",
id="first_name",
),
rx.chakra.input(
placeholder="Last Name", id="last_name"
),
rx.chakra.hstack(
rx.chakra.checkbox("Checked", id="check"),
rx.chakra.switch("Switched", id="switch"),
),
rx.chakra.button("Submit",
type_="submit",
bg="#ecfdf5",
color="#047857",
border_radius="lg",
),
),
on_submit=FormState.handle_submit,
),
rx.chakra.divider(),
rx.chakra.heading("Results"),
rx.chakra.text(FormState.form_data.to_string()),
width="100%",
)"""
color = "rgb(107,99,246)"
forms_1_state = """class FormState(rx.State):
form_data: dict = {}
def handle_submit(self, form_data: dict):
"Handle the form submit."
self.form_data = form_data"""
forms_2_code = """rx.chakra.vstack(
rx.upload(
rx.chakra.vstack(
rx.chakra.button(
"Select File",
color=color,
bg="white",
border=f"1px solid {color}",
),
rx.chakra.text(
"Drag and drop files here or click to select files"
),
),
border=f"1px dotted {color}",
padding="5em",
),
rx.chakra.hstack(rx.foreach(rx.selected_files, rx.chakra.text)),
rx.chakra.button(
"Upload",
on_click=lambda: UploadState.handle_upload(
rx.upload_files()
),
),
rx.chakra.button(
"Clear",
on_click=rx.clear_selected_files,
),
rx.foreach(
UploadState.img, lambda img: rx.chakra.image(src=img, width="20%", height="auto",)
),
padding="5em",
width="100%",
)"""
forms_2_state = """class UploadState(State):
"The app state."
# The images to show.
img: list[str]
async def handle_upload(
self, files: list[rx.UploadFile]
):
"Handle the upload of file(s).
Args:
files: The uploaded files.
"
for file in files:
upload_data = await file.read()
outfile = rx.get_asset_path(file.filename)
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
self.img.append(f"/{file.filename}")"""
def forms_page() -> rx.Component:
"""The UI for the settings page.
Returns:
rx.Component: The UI for the settings page.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.heading(
"Forms Demo",
font_size="3em",
),
rx.chakra.vstack(
rx.chakra.form(
rx.chakra.vstack(
rx.chakra.input(
placeholder="First Name",
id="first_name",
),
rx.chakra.input(placeholder="Last Name", id="last_name"),
rx.chakra.hstack(
rx.chakra.checkbox("Checked", id="check"),
rx.chakra.switch("Switched", id="switch"),
),
rx.chakra.button(
"Submit",
type_="submit",
bg="#ecfdf5",
color="#047857",
border_radius="lg",
),
),
on_submit=FormState.handle_submit,
),
rx.chakra.divider(),
rx.chakra.heading("Results"),
rx.chakra.text(FormState.form_data.to_string()),
width="100%",
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("State", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
forms_1_code,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
forms_1_state,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
rx.chakra.heading("Upload Example", font_size="3em"),
rx.chakra.text("Try uploading some images and see how they look."),
rx.chakra.vstack(
rx.upload(
rx.chakra.vstack(
rx.chakra.button(
"Select File",
color=color,
bg="white",
border=f"1px solid {color}",
),
rx.chakra.text(
"Drag and drop files here or click to select files"
),
),
border=f"1px dotted {color}",
padding="5em",
),
rx.chakra.hstack(rx.foreach(rx.selected_files, rx.chakra.text)),
rx.chakra.button(
"Upload",
on_click=lambda: UploadState.handle_upload(rx.upload_files()),
),
rx.chakra.button(
"Clear",
on_click=rx.clear_selected_files,
),
rx.foreach(
UploadState.img,
lambda img: rx.chakra.image(
src=img,
width="20%",
height="auto",
),
),
padding="5em",
width="100%",
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("State", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
forms_2_code,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
forms_2_state,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
style=template_content_style,
),
style=template_page_style,
)

View File

@ -1,252 +0,0 @@
"""The dashboard page for the template."""
import reflex as rx
from ..states.pie_state import PieChartState
from ..styles import *
data_1 = [
{"name": "Page A", "uv": 4000, "pv": 2400, "amt": 2400},
{"name": "Page B", "uv": 3000, "pv": 1398, "amt": 2210},
{"name": "Page C", "uv": 2000, "pv": 9800, "amt": 2290},
{"name": "Page D", "uv": 2780, "pv": 3908, "amt": 2000},
{"name": "Page E", "uv": 1890, "pv": 4800, "amt": 2181},
{"name": "Page F", "uv": 2390, "pv": 3800, "amt": 2500},
{"name": "Page G", "uv": 3490, "pv": 4300, "amt": 2100},
]
data_1_show = """[
{"name": "Page A", "uv": 4000, "pv": 2400, "amt": 2400},
{"name": "Page B", "uv": 3000, "pv": 1398, "amt": 2210},
{"name": "Page C", "uv": 2000, "pv": 9800, "amt": 2290},
{"name": "Page D", "uv": 2780, "pv": 3908, "amt": 2000},
{"name": "Page E", "uv": 1890, "pv": 4800, "amt": 2181},
{"name": "Page F", "uv": 2390, "pv": 3800, "amt": 2500},
{"name": "Page G", "uv": 3490, "pv": 4300, "amt": 2100},
]"""
graph_1_code = """rx.recharts.composed_chart(
rx.recharts.area(
data_key="uv", stroke="#8884d8", fill="#8884d8"
),
rx.recharts.bar(
data_key="amt", bar_size=20, fill="#413ea0"
),
rx.recharts.line(
data_key="pv", type_="monotone", stroke="#ff7300"
),
rx.recharts.x_axis(data_key="name"),
rx.recharts.y_axis(),
rx.recharts.cartesian_grid(stroke_dasharray="3 3"),
rx.recharts.graphing_tooltip(),
data=data,
)"""
graph_2_code = """rx.recharts.pie_chart(
rx.recharts.pie(
data=PieChartState.resources,
data_key="count",
name_key="type_",
cx="50%",
cy="50%",
start_angle=180,
end_angle=0,
fill="#8884d8",
label=True,
),
rx.recharts.graphing_tooltip(),
),
rx.chakra.vstack(
rx.foreach(
PieChartState.resource_types,
lambda type_, i: rx.chakra.hstack(
rx.chakra.button(
"-",
on_click=PieChartState.decrement(type_),
),
rx.chakra.text(
type_,
PieChartState.resources[i]["count"],
),
rx.chakra.button(
"+",
on_click=PieChartState.increment(type_),
),
),
),
)"""
graph_2_state = """class PieChartState(rx.State):
resources: list[dict[str, Any]] = [
dict(type_="🏆", count=1),
dict(type_="🪵", count=1),
dict(type_="🥑", count=1),
dict(type_="🧱", count=1),
]
@rx.cached_var
def resource_types(self) -> list[str]:
return [r["type_"] for r in self.resources]
def increment(self, type_: str):
for resource in self.resources:
if resource["type_"] == type_:
resource["count"] += 1
break
def decrement(self, type_: str):
for resource in self.resources:
if (
resource["type_"] == type_
and resource["count"] > 0
):
resource["count"] -= 1
break
"""
def graphing_page() -> rx.Component:
"""The UI for the dashboard page.
Returns:
rx.Component: The UI for the dashboard page.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.heading(
"Graphing Demo",
font_size="3em",
),
rx.chakra.heading(
"Composed Chart",
font_size="2em",
),
rx.chakra.stack(
rx.recharts.composed_chart(
rx.recharts.area(data_key="uv", stroke="#8884d8", fill="#8884d8"),
rx.recharts.bar(data_key="amt", bar_size=20, fill="#413ea0"),
rx.recharts.line(data_key="pv", type_="monotone", stroke="#ff7300"),
rx.recharts.x_axis(data_key="name"),
rx.recharts.y_axis(),
rx.recharts.cartesian_grid(stroke_dasharray="3 3"),
rx.recharts.graphing_tooltip(),
data=data_1,
# height="15em",
),
width="100%",
height="20em",
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("Data", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
graph_1_code,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
data_1_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
rx.chakra.heading("Interactive Example", font_size="2em"),
rx.chakra.hstack(
rx.recharts.pie_chart(
rx.recharts.pie(
data=PieChartState.resources,
data_key="count",
name_key="type_",
cx="50%",
cy="50%",
start_angle=180,
end_angle=0,
fill="#8884d8",
label=True,
),
rx.recharts.graphing_tooltip(),
),
rx.chakra.vstack(
rx.foreach(
PieChartState.resource_types,
lambda type_, i: rx.chakra.hstack(
rx.chakra.button(
"-",
on_click=PieChartState.decrement(type_),
),
rx.chakra.text(
type_,
PieChartState.resources[i]["count"],
),
rx.chakra.button(
"+",
on_click=PieChartState.increment(type_),
),
),
),
),
width="100%",
height="15em",
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("State", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
graph_2_code,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
graph_2_state,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
style=template_content_style,
min_h="100vh",
),
style=template_page_style,
min_h="100vh",
)

View File

@ -1,55 +0,0 @@
"""The home page of the app."""
import reflex as rx
from ..styles import *
def home_page() -> rx.Component:
"""The UI for the home page.
Returns:
rx.Component: The UI for the home page.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.heading(
"Welcome to Reflex! 👋",
font_size="3em",
),
rx.chakra.text(
"Reflex is an open-source app framework built specifically to allow you to build web apps in pure python. 👈 Select a demo from the sidebar to see some examples of what Reflex can do!",
),
rx.chakra.heading(
"Things to check out:",
font_size="2em",
),
rx.chakra.unordered_list(
rx.chakra.list_item(
"Take a look at ",
rx.chakra.link(
"reflex.dev",
href="https://reflex.dev",
color="rgb(107,99,246)",
),
),
rx.chakra.list_item(
"Check out our ",
rx.chakra.link(
"docs",
href="https://reflex.dev/docs/getting-started/introduction/",
color="rgb(107,99,246)",
),
),
rx.chakra.list_item(
"Ask a question in our ",
rx.chakra.link(
"community",
href="https://discord.gg/T5WSbC2YtQ",
color="rgb(107,99,246)",
),
),
),
style=template_content_style,
),
style=template_page_style,
)

View File

@ -1,178 +0,0 @@
"""Sidebar component for the app."""
import reflex as rx
from .state import State
from .styles import *
def sidebar_header() -> rx.Component:
"""Sidebar header.
Returns:
rx.Component: The sidebar header component.
"""
return rx.chakra.hstack(
rx.chakra.image(
src="/icon.svg",
height="2em",
),
rx.chakra.spacer(),
rx.chakra.link(
rx.chakra.center(
rx.chakra.image(
src="/github.svg",
height="3em",
padding="0.5em",
),
box_shadow=box_shadow,
bg="transparent",
border_radius=border_radius,
_hover={
"bg": accent_color,
},
),
href="https://github.com/reflex-dev/reflex",
),
width="100%",
border_bottom=border,
padding="1em",
)
def sidebar_footer() -> rx.Component:
"""Sidebar footer.
Returns:
rx.Component: The sidebar footer component.
"""
return rx.chakra.hstack(
rx.chakra.link(
rx.chakra.center(
rx.chakra.image(
src="/paneleft.svg",
height="2em",
padding="0.5em",
),
bg="transparent",
border_radius=border_radius,
**hover_accent_bg,
),
on_click=State.toggle_sidebar_displayed,
transform=rx.cond(~State.sidebar_displayed, "rotate(180deg)", ""),
transition="transform 0.5s, left 0.5s",
position="relative",
left=rx.cond(State.sidebar_displayed, "0px", "20.5em"),
**overlapping_button_style,
),
rx.chakra.spacer(),
rx.chakra.link(
rx.chakra.text(
"Docs",
),
href="https://reflex.dev/docs/getting-started/introduction/",
),
rx.chakra.link(
rx.chakra.text(
"Blog",
),
href="https://reflex.dev/blog/",
),
width="100%",
border_top=border,
padding="1em",
)
def sidebar_item(text: str, icon: str, url: str) -> rx.Component:
"""Sidebar item.
Args:
text (str): The text of the item.
icon (str): The icon of the item.
url (str): The URL of the item.
Returns:
rx.Component: The sidebar item component.
"""
return rx.chakra.link(
rx.chakra.hstack(
rx.chakra.image(
src=icon,
height="2.5em",
padding="0.5em",
),
rx.chakra.text(
text,
),
bg=rx.cond(
State.origin_url == f"/{text.lower()}/",
accent_color,
"transparent",
),
color=rx.cond(
State.origin_url == f"/{text.lower()}/",
accent_text_color,
text_color,
),
border_radius=border_radius,
box_shadow=box_shadow,
width="100%",
padding_x="1em",
),
href=url,
width="100%",
)
def sidebar() -> rx.Component:
"""Sidebar.
Returns:
rx.Component: The sidebar component.
"""
return rx.chakra.box(
rx.chakra.vstack(
sidebar_header(),
rx.chakra.vstack(
sidebar_item(
"Welcome",
"/github.svg",
"/",
),
sidebar_item(
"Graphing Demo",
"/github.svg",
"/graphing",
),
sidebar_item(
"Data Table Demo",
"/github.svg",
"/datatable",
),
sidebar_item(
"Forms Demo",
"/github.svg",
"/forms",
),
sidebar_item(
"Chat App Demo",
"/github.svg",
"/chatapp",
),
width="100%",
overflow_y="auto",
align_items="flex-start",
padding="1em",
),
rx.chakra.spacer(),
sidebar_footer(),
height="100dvh",
),
display=["none", "none", "block"],
min_width=sidebar_width,
height="100%",
position="sticky",
top="0px",
border_right=border,
)

View File

@ -1,22 +0,0 @@
"""Base state for the app."""
import reflex as rx
class State(rx.State):
"""State for the app."""
sidebar_displayed: bool = True
@rx.var
def origin_url(self) -> str:
"""Get the url of the current page.
Returns:
str: The url of the current page.
"""
return self.router_data.get("asPath", "")
def toggle_sidebar_displayed(self) -> None:
"""Toggle the sidebar displayed."""
self.sidebar_displayed = not self.sidebar_displayed

View File

@ -1,40 +0,0 @@
import reflex as rx
from ..state import State
class FormState(State):
"""Form state."""
form_data: dict = {}
def handle_submit(self, form_data: dict):
"""Handle the form submit.
Args:
form_data: The form data.
"""
self.form_data = form_data
class UploadState(State):
"""The app state."""
# The images to show.
img: list[str]
async def handle_upload(self, files: list[rx.UploadFile]):
"""Handle the upload of file(s).
Args:
files: The uploaded files.
"""
for file in files:
upload_data = await file.read()
outfile = rx.get_asset_path(file.filename)
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
self.img.append(f"/{file.filename}")

View File

@ -1,47 +0,0 @@
from typing import Any
import reflex as rx
from ..state import State
class PieChartState(State):
"""Pie Chart State."""
resources: list[dict[str, Any]] = [
dict(type_="🏆", count=1),
dict(type_="🪵", count=1),
dict(type_="🥑", count=1),
dict(type_="🧱", count=1),
]
@rx.cached_var
def resource_types(self) -> list[str]:
"""Get the resource types.
Returns:
The resource types.
"""
return [r["type_"] for r in self.resources]
def increment(self, type_: str):
"""Increment the count of a resource type.
Args:
type_: The type of resource to increment.
"""
for resource in self.resources:
if resource["type_"] == type_:
resource["count"] += 1
break
def decrement(self, type_: str):
"""Decrement the count of a resource type.
Args:
type_: The type of resource to decrement.
"""
for resource in self.resources:
if resource["type_"] == type_ and resource["count"] > 0:
resource["count"] -= 1
break

View File

@ -1,67 +0,0 @@
"""Styles for the app."""
import reflex as rx
from .state import State
border_radius = "0.375rem"
box_shadow = "0px 0px 0px 1px rgba(84, 82, 95, 0.14)"
border = "1px solid #F4F3F6"
text_color = "black"
accent_text_color = "#1A1060"
accent_color = "#F5EFFE"
hover_accent_color = {"_hover": {"color": accent_color}}
hover_accent_bg = {"_hover": {"bg": accent_color}}
content_width_vw = "90vw"
sidebar_width = "20em"
template_page_style = {
"padding_top": "5em",
"padding_x": "2em",
}
template_content_style = {
"width": rx.cond(
State.sidebar_displayed,
f"calc({content_width_vw} - {sidebar_width})",
content_width_vw,
),
"min-width": sidebar_width,
"align_items": "flex-start",
"box_shadow": box_shadow,
"border_radius": border_radius,
"padding": "1em",
"margin_bottom": "2em",
}
link_style = {
"color": text_color,
"text_decoration": "none",
**hover_accent_color,
}
overlapping_button_style = {
"background_color": "white",
"border": border,
"border_radius": border_radius,
}
base_style = {
rx.chakra.MenuButton: {
"width": "3em",
"height": "3em",
**overlapping_button_style,
},
rx.chakra.MenuItem: hover_accent_bg,
}
tab_style = {
"color": "#494369",
"font_weight": 600,
"_selected": {
"color": "#5646ED",
"bg": "#F5EFFE",
"padding_x": "0.5em",
"padding_y": "0.25em",
"border_radius": "8px",
},
}

View File

@ -1,4 +0,0 @@
from .loading_icon import loading_icon
from .modal import modal
from .navbar import navbar
from .sidebar import sidebar

View File

@ -1,118 +0,0 @@
import reflex as rx
from ...webui import styles
from ...webui.components import loading_icon
from ...webui.state import QA, State
def message(qa: QA) -> rx.Component:
"""A single question/answer message.
Args:
qa: The question/answer pair.
Returns:
A component displaying the question/answer pair.
"""
return rx.chakra.box(
rx.chakra.box(
rx.chakra.text(
qa.question,
bg=styles.border_color,
shadow=styles.shadow_light,
**styles.message_style,
),
text_align="right",
margin_top="1em",
),
rx.chakra.box(
rx.chakra.text(
qa.answer,
bg=styles.accent_color,
shadow=styles.shadow_light,
**styles.message_style,
),
text_align="left",
padding_top="1em",
),
width="100%",
)
def chat() -> rx.Component:
"""List all the messages in a single conversation.
Returns:
A component displaying all the messages in a single conversation.
"""
return rx.chakra.vstack(
rx.chakra.box(rx.foreach(State.chats[State.current_chat], message)),
py="8",
flex="1",
width="100%",
max_w="3xl",
padding_x="4",
align_self="center",
overflow="hidden",
padding_bottom="5em",
**styles.base_style[rx.chakra.Vstack],
)
def action_bar() -> rx.Component:
"""The action bar to send a new message.
Returns:
The action bar to send a new message.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.form(
rx.chakra.form_control(
rx.chakra.hstack(
rx.chakra.input(
placeholder="Type something...",
value=State.question,
on_change=State.set_question,
_placeholder={"color": "#fffa"},
_hover={"border_color": styles.accent_color},
style=styles.input_style,
),
rx.chakra.button(
rx.cond(
State.processing,
loading_icon(height="1em"),
rx.chakra.text("Send"),
),
type_="submit",
_hover={"bg": styles.accent_color},
style=styles.input_style,
),
**styles.base_style[rx.chakra.Hstack],
),
is_disabled=State.processing,
),
on_submit=State.process_question,
width="100%",
),
rx.chakra.text(
"ReflexGPT may return factually incorrect or misleading responses. Use discretion.",
font_size="xs",
color="#fff6",
text_align="center",
),
width="100%",
max_w="3xl",
mx="auto",
**styles.base_style[rx.chakra.Vstack],
),
position="sticky",
bottom="0",
left="0",
py="4",
backdrop_filter="auto",
backdrop_blur="lg",
border_top=f"1px solid {styles.border_color}",
align_items="stretch",
width="100%",
)

View File

@ -1,26 +0,0 @@
import reflex as rx
class LoadingIcon(rx.Component):
"""A custom loading icon component."""
library = "react-loading-icons"
tag = "SpinningCircles"
stroke: rx.Var[str]
stroke_opacity: rx.Var[str]
fill: rx.Var[str]
fill_opacity: rx.Var[str]
stroke_width: rx.Var[str]
speed: rx.Var[str]
height: rx.Var[str]
def get_event_triggers(self) -> dict:
"""Get the event triggers that pass the component's value to the handler.
Returns:
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {"on_change": lambda status: [status]}
loading_icon = LoadingIcon.create

View File

@ -1,56 +0,0 @@
import reflex as rx
from ...webui.state import State
def modal() -> rx.Component:
"""A modal to create a new chat.
Returns:
The modal component.
"""
return rx.chakra.modal(
rx.chakra.modal_overlay(
rx.chakra.modal_content(
rx.chakra.modal_header(
rx.chakra.hstack(
rx.chakra.text("Create new chat"),
rx.chakra.icon(
tag="close",
font_size="sm",
on_click=State.toggle_modal,
color="#fff8",
_hover={"color": "#fff"},
cursor="pointer",
),
align_items="center",
justify_content="space-between",
)
),
rx.chakra.modal_body(
rx.chakra.input(
placeholder="Type something...",
on_blur=State.set_new_chat_name,
bg="#222",
border_color="#fff3",
_placeholder={"color": "#fffa"},
),
),
rx.chakra.modal_footer(
rx.chakra.button(
"Create",
bg="#5535d4",
box_shadow="md",
px="4",
py="2",
h="auto",
_hover={"bg": "#4c2db3"},
on_click=State.create_chat,
),
),
bg="#222",
color="#fff",
),
),
is_open=State.modal_open,
)

Some files were not shown because too many files have changed in this diff Show More