Skip to content

Releases: reflex-dev/reflex

v0.6.4

29 Oct 23:45
e471dc1
Compare
Choose a tag to compare

New Features

Make Var System Expandable

A new dispatch mechanism for converting python values into Var and LiteralVar subclasses. This allows component authors and downstream applications to better support custom frontend operations on Python values converted to Javascript values

See Example

This example allows for near drop-in support for working with SQLAlchemy DeclarativeBase models and will likely be included in a future release:

from collections.abc import Mapping, MutableSet, Sequence
from typing import TypeVar
import dataclasses
import sys

import reflex as rx
import sqlalchemy
import sqlalchemy.orm.exc
from sqlalchemy.orm import DeclarativeBase


class DeclarativeBaseVar(rx.vars.ObjectVar, python_types=DeclarativeBase):
    pass


@dataclasses.dataclass(
    eq=False,
    frozen=True,
    **{"slots": True} if sys.version_info >= (3, 10) else {},
)
class LiteralDeclarativeBaseVar(rx.vars.LiteralObjectVar, DeclarativeBaseVar):
    _var_value: DeclarativeBase | None = None


T = TypeVar("T")
K = TypeVar("K")
V = TypeVar("V")


@rx.serializer
def serialize_Sequence(s: Sequence[T] | MutableSet[T]) -> list[T]:
    return list(s)


@rx.serializer
def serialize_Mapping(m: Mapping[K, V]) -> dict[K, V]:
    return dict(m)


@rx.serializer
def serialize_DeclarativeBase(obj: DeclarativeBase) -> dict[str, str]:
    s = {}
    for attr in sqlalchemy.inspect(type(obj)).all_orm_descriptors.keys():
        try:
            s[attr] = getattr(obj, attr)
        except sqlalchemy.orm.exc.DetachedInstanceError:
            # This happens when the relationship was never loaded and the session is closed.
            continue
    return s

max-requests support to gunicorn (fixed memory leak)

This is a new configurable option in the rx.config but also now has default values.
gunicorn_max_requests - ( gunicorn / uvicorn )max requests per worker
Defaults value - 100
gunicorn_max_requests_jitter - (gunicorn only) variance in the max request limit. To prevent all workers restarting at same time
Defaults value - 25

What is max_requests?

max_requests is a the maximum number of requests a worker can serve before the manager will kill the worker and restart.

Why is this needed?

gunicorn workers don't release memory after a request. This can cause for a workers to hold on to more and more memory over time. Setting this flag means that after serving N requests the worker is killed, thus releasing the memory, and a new worker is spun up.

How to configure

rx.config(
    ...
     gunicorn_max_requests=50
    ...
)

Experimental Shiki Codeblock

rx._x.code_block(
"""
print("Original text")   # [!code --]
print("Replace original with this") # [!code ++]

name = "John Doe"  # [!code highlight]
""",
    language="python",
    theme="dracula",
    use_transformers=True,
    can_copy=True,
    show_line_numbers=True
)

dotenv support added

To use this feature, you must install python-dotenv separately from reflex.

import reflex as rx

config = rx.Config(
    app_name="mycoolapp",
    env_file=".env",
)

New rx.dynamic decorator

Unlike normal UI functions, this decorator allows UI code to directly access State instance values, Python-only APIs, and typical for and if statements.

See Example

We can implement a simple Reflex fiddle, that evaluates component strings into UI components and render them. This was previously difficult, as all UI had to compile into react code in the .web folder. This works by dynamically compiling a JavaScript module using in-window react.

import reflex as rx


class State(rx.State):
    component_str = "rx.button('login')"


@rx.dynamic
def evaluated_component(state: State):
    try:
        component = eval(
            state.component_str,
            {
                "rx": rx,
                "State": State,
            },
        )
    except Exception as e:
        return rx.text(f"Error: {e}")
    if not isinstance(component, rx.Component):
        return rx.text("Invalid component")
    return component


def index():
    return (
        rx.hstack(
            rx.text_area(
                value=State.component_str,
                on_change=State.set_component_str,
                height="100%",
                flex="1",
            ),
            rx.card(evaluated_component(), height="100%", flex="1"),
            height="100vh",
            padding="1rem",
            box_size="border-box",
        ),
    )

Improvements

Better Type Hinting for Built in Components

Other Improvements

Bug Fixes

Version Bumps

Other Changes

Full Changelog: v0.6.3.post1...v0.6.4

v0.6.3.post1

23 Oct 23:17
9308caa
Compare
Choose a tag to compare

Post-release fix for hot reload issue RuntimeError: Cannot populate parent states

  • [ENG-3989] Ensure non-serialized states are present in StateManagerDisk (#4230)

Full Changelog: v0.6.3...v0.6.3.post1

v0.6.3

18 Oct 16:23
addf633
Compare
Choose a tag to compare

New Features

Correct handling of aria and data props

Any props passed to a component with aria_ or data_ prefix will be applied directly to the component (previously, these were misinterpreted as style props).

Reflex Code

rx.icon_button("save", aria_label="Save Changes", data_test="arbitrary data")

Generated Output

<button ... aria-label="Save Changes" data-test="arbitrary data"><svg>...</svg></button>

Improvements

Static typing of events and vars

New (optional) rx.Field, rx.field and @rx.event decorators allow pyright and other static type checkers to better understand how event handlers and state vars are handled in reflex, allowing most static type checking to pass without # type: ignore comments.

import reflex as rx


class MyState(rx.State):
    v: rx.Field[int] = rx.field(42)

    @rx.event
    def set_v(self, v: str):
        try:
            self.v = int(v)
        except ValueError:
            pass


def index() -> rx.Component:
    return rx.vstack(
        rx.heading(MyState.v),
        rx.input(
            value=MyState.v,
            on_change=MyState.set_v,
            type="number",
        ),
    )


app = rx.App()
app.add_page(index)
  • [ENG-3749] type safe vars by @adhami3310 in #4066
  • add type hinting to events by @adhami3310 in #4145
    • Fix runtime error on python 3.11.0 (#4197)
    • fix pyi for untyped event handlers (#4186)
    • Arbitrary arg access two levels deep for untyped handler (#4180)

Other Improvements

  • Optimize StateManagerDisk by @masenf in #4056
  • Reduce pickle size by @masenf in #4063
  • fail safely when pickling by @adhami3310 in #4085
  • First use environment variable as npm registry by @ruhz3 in #4082
  • let users pick state manager mode by @Lendemor in #4041
    • disk is memory is disk (#4185)
    • When REDIS_URL is set, use redis, regardless of config preference. (#4196)
  • Allow setting a different invocation function for EventChain by @masenf in #4160

Bug Fixes

Version Bumps

Documentation

Other Changes

New Contributors

Read more

v0.6.2.post1

09 Oct 18:58
289c21e
Compare
Choose a tag to compare

Hotfix for Upload

Pin attr-accept package to 2.2.2 to avoid breakage introduced in 2.2.3 (Released 2024-10-09)

Full Changelog: v0.6.2...v0.6.2.post1

v0.6.2

08 Oct 16:21
e637f48
Compare
Choose a tag to compare

Known Issues

There is an error persisting states that are created inside a function #4128

def dynamic_state():
    class _DynamicState(rx.State):
        dynamic: str = ""

    return _DynamicState

DynamicState = dynamic_state()

AttributeError: Can't pickle local object 'dynamic_state.<locals>._DynamicState'

Improvements

  • All SVG elements are now supported
  • Event triggers can now use rx.cond
  • Faster state serialization by replacing dill with normal pickle
    • [ENG-3867] Garden Variety Pickle by @masenf in #4054
    • fail safely when pickling (#4085)

Bug Fixes

  • Handle primary_key defined in sa_column
  • [ENG-3870] rx.call_script with f-string var produces incorrect code by @masenf in #4039
  • Get default for backend var defined in mixin (#4060)
  • catch CancelledError in lifespan hack for windows (#4083)
  • convert literal type to its variants (#4062)

Dynamic Components

Error Messages

Other Changes

New Contributors

Full Changelog: v0.6.1...v0.6.2

v0.6.1

01 Oct 00:25
b88a17a
Compare
Choose a tag to compare

Regression Fixes

New Features

Experimental Dynamic Components

In this release, state vars can be of rx.Component type and @rx.var computed vars can return rx.Component, allowing dynamic component structures to be created on the backend at runtime. This enables the full use of python expressions in generated components, as opposed to rx.cond and rx.foreach.

There are performance implications when using dynamic components so prefer static components where possible.

Run Backend with Granian server

install granian package and set REFLEX_USE_GRANIAN=1 to run with the new, experimental granian backend (instead of the default uvicorn).

REFLEX_USE_SYSTEM_NODE and REFLEX_USE_SYSTEM_BUN

If you prefer to run your own versions of node and bun, ensure they are on the PATH and set these environment variables to 1.

  • add env var to enable using system node and bun by @Lendemor in #4006

Improvements

Bump nextjs to 14.2.13

Miscellaneous

Bug Fixes

Documentation

  • fix: Adding in-line comments for the segmented control: value and on_change by @elviskahoro in #3933
  • fix: Adding code comments for segmented control type by @elviskahoro in #3935

Other Changes

New Contributors

Full Changelog: v0.6.0...v0.6.1

v0.6.0

24 Sep 22:13
2b17a32
Compare
Choose a tag to compare

Overview of Changes from 0.5.0 to 0.6.0

Breaking Changes

Drop support for python 3.8

  • bump python>=3.10 for 0.6.0 (#3956)
  • Bring back py3.9 support with a deprecation warning. (#3976)

Remove Deprecated Features

  • rx.input.root (0.5.0)
  • rx.Component._apply_theme (0.5.0)
  • _type, _min, _max prop rewriting (0.4.0)
  • Passing props to rx.foreach (0.5.0)
  • rx.el aliases for defs, lineargradient, stop, path (use rx.el.svg namespace)
  • Lucide icons that were removed upstream (0.4.6)
  • passing children to rx.color_mode.button (0.5.0)
  • rx.cached_var (0.5.6)
  • Specifying REDIS_URL without a url scheme (0.3.6)

PRs

New Var System

A Var is a placeholder for a value which is sent to the frontend or rendered as Javascript code in the app. Most users of Reflex do not interact with the var system directly, but it becomes relevant for advanced users that are wrapping components or handling custom types.

  • rx.Var.create(...) now returns a LiteralVar subclass wrapping the provided value.
    • _var_is_string is deprecated, passing a string will always create a StringVar
  • rx.Var(...) returns an ImmutableVar representing a raw javascript expression.
    • Replaces the deprecated _var_is_local param
  • Vars are not automatically cast as bool, when passing a non-bool var to a prop that expects a boolean, add .bool() after the var -- error message will include this hint.

The new Var system brings a much more accurate translation of literal python values into javascript, especially of object and array types.

rx.chakra removed from main repo

First, pip install reflex-chakra. Then import reflex_chakra as rc. rx.chakra will still work until 0.7.0, but it is recommended to move now to avoid deprecation warning.

Var Shadowing Detection

When a dynamic route arg name conflicts with the name of an existing state Var, the framework will raise DynamicRouteArgShadowsStateVar. This is intended to avoid unexpected behavior wherein the dynamic var takes precedence over the state var, even in a substate. A fix for the underlying cause is forthcoming.

In the meantime, define any pages that use dynamic route arguments early, so the dynamic var is available for use in the page functions.


When a computed var name conflicts with the name of an existing state Var, the framework will raise ComputedVarShadowsStateVar.

rx.progress is now Radix Themes Progress

The previous Radis Primitives progress is available as rx.radix.primitives.progress

Watchfiles dependency removed

If you are upgrading reflex in an existing environment run pip uninstall watchfiles first to ensure the hot reload mechanism is properly ignoring the .web directory.

New Features

DiskStateManager - preserve state across hot reloads in dev mode

/_health endpoint

http://localhost:8000/_health
{"status":true,"db":true,"redis":false}

Improvements

Var System

  • fully migrate vars into new system by @adhami3310 in #3743
  • guess_type: if the type is optional, treat it like it's "not None" by @masenf in #3839
  • Fix double-quoting of defaultColorMode by @masenf in #3840
  • ImmutableVar perf optimizations by @masenf in #3814
  • Get attribute access type fix by @benedikt-bartscher in #3803
  • fix var in bare by @adhami3310 in #3873
  • add var_operation and move some operations to the new style by @adhami3310 in #3841
  • Adding array to array pluck operation. by @abulvenz in #3868
  • simplify ImmutableComputedVar.get by @benedikt-bartscher in #3902
  • Use old serializer system in LiteralVar by @adhami3310 in #3875
  • Fix type propagation in ToStringOperation by @abulvenz in #3895
  • [ENG-3833] handle object in is bool (#3974)
  • suggest bool() for wrong values (#3975)
  • use is true for bool var (#3973)
  • Add shim for format_event_chain (#3958)
  • use serializer before serializing base yourself (#3960)
  • [ENG-3817] deprecate _var_name_unwrapped (instead of removing it) (#3951)
  • move the filterwarning to appropriate file (#3952)
  • fix unionize recursion (#3948)
  • add special handling for infinity and nan (#3943)
  • use is true (#3946)
  • use serializer for state update and rework serializers (#3934)
  • replace old var system with immutable one (#3916)
  • Remove Pydantic from some classes (#3907)

Documentation / Error Messages

  • Add comments to DataList components by @elviskahoro in #3827
  • [REF-3589] raise EventHandlerArgMismatch when event handler args don't match spec by @masenf in #3853
  • better errors in state.py (#3929)

Other Changes

Bug Fixes

New Contributors

Full Changelog: v0.5.10...v0.6.0

v0.5.10

28 Aug 16:41
ecf222d
Compare
Choose a tag to compare

Improvements

  • add message when installing requirements.txt is needed for chosen template during init by @Lendemor in #3750
  • use different registry when in china, fixes #3700 by @adhami3310 in #3702
  • [REF-3536][REF-3537][REF-3541]Move chakra components into its repo(reflex-chakra) by @ElijahAhianyo in #3798
    • Preparing for the eventual removal of chakra from the core reflex package
  • Recognize SSL_NO_VERIFY=1 to disable certificate verification when downloading tools like bun and fnm #3846

Bug Fixes

Other Changes

New Contributors

Full Changelog: v0.5.9...v0.5.10

v0.5.9

06 Aug 23:25
72465a7
Compare
Choose a tag to compare

Bug Fixes

Doc Updates

Var Refactor

This release includes some new experimental features being developed incrementally in reflex._x.vars.

Full Changelog: v0.5.8...v0.5.9

v0.5.8

29 Jul 19:59
e80315d
Compare
Choose a tag to compare

New Features

  • update init prompt to use new templates from reflex-dev/templates by @Lendemor in #3677

Improvements

Bug Fixes

  • debounce: pass through key and special_props by @masenf in #3655
  • [REF-3135]Radix Primitive components should not ignore provided class_name prop by @ElijahAhianyo in #3676
  • [REF-3101] rx.list Dont set/hardcode list_style_position css prop by @ElijahAhianyo in #3695
  • [REF-3184] [REF-3339] Background task locking improvements by @masenf in #3696
  • [REF-3375] useMemo on generateUUID props to maintain consistent value by @masenf in #3708
  • Define BaseVar fields on ComputedVar by @paoloemilioserra in #3659

Var Refactor

This release includes some new experimental features being developed incrementally in reflex._x.vars.

Other Changes

New Contributors

Full Changelog: v0.5.7...reflex-0.5.8