Skip to content

Releases: reflex-dev/reflex

v0.2.9

09 Oct 22:43
86c624e
Compare
Choose a tag to compare

Breaking Changes

rx.constants module refactored

  • Many names have changed for better organization and namespacing of the growing number of constant values.
    • rx.constants is not really a public API, but some existing code may have been accessing values in this module.
  • code cleanup (split constants into a folder) by @Lendemor in #1866

New Features

Core Graphing Library is now Recharts

The API for rendering charts and graphs has changed.

  • See the docs for examples and more information.
  • Victory charts are deprecated and will be removed in a subsequent release.
    • rx.data is no longer used.
  • #1878

Run Arbitrary Javascript from Event Handler

  • rx.call_script: a real EventHandler to execute arbitrary javascript by @masenf in #1860

Redirect into New Window

  • return rx.redirect("https://google.com", external=True) to open page in new tab/window
  • allow external link for redirect by @Lendemor in #1902

HTML Editor Component

Improvements

  • Allow arbitrary Reflex components to map to markdown tags for more customizable styling.
  • Include scripts in <head> for every page by setting head_components prop in rx.App
  • Adding Missing Props to button, button_group, and circular_progress
  • Add Readme.md for turkish language by @09u2h4n in #1922
  • Pin frontend package versions by @picklelo in #1920
    • More reliable deploys without bringing in unexpected upstream changes

Bug Fixes

  • component: imports override _get_dependencies_imports by @masenf in #1859
  • Fix regression where rx.table stopped working with state Var
  • MutableProxy fixes when accessing list, dict, or set vars on a State
    • MutableProxy wraps values yielded by __iter__ by @masenf in #1876
    • State.reset uses deepcopy on defaults by @masenf in #1889
    • state: get_value unwraps MutableProxy first by @masenf in #1887
    • state: subclass of MutableState must return _mark_dirty return value by @masenf in #1898
  • fix rx.image src not working with state by @Lendemor in #1915
  • fix menu items= API by @Lendemor in #1905

Other Changes

New Contributors

Full Changelog: v0.2.8...v0.3.0

v0.2.8

22 Sep 17:57
83d7a04
Compare
Choose a tag to compare

✨ This release is made possible in part by users like YOU! ✨

Breaking Changes

CopyToClipboard component has been removed.

Use the rx.set_clipboard special event instead.

New Features

get_event_triggers API

The new Component.get_event_triggers API combines the old get_triggers and get_controlled_triggers methods into a unified API (the previous methods will continue to work in 0.2.8, but wrapped components should move to the new API).

The new API is more flexible, providing control over handler and trigger argument mapping. The method is expected to return a dictionary of callables. The keys are the names of the triggers in the react component. The values are callables whose signature defines the javascript trigger signature and the return value is a list of args that will be passed to the python EventHandler function.

This allows wrapping of components that accept non-standard event handler functions. Typically a lambda is used to map arguments, but a regular function with type annotations can also be used to enable extended Var operations like indexing.

For example, the FormSelect component uses a non-standard signature for on_change, this can now be accomodated in the new API.

class FormSelect(rx.Component):
    library = "@patternfly/react-core"
    tag = "FormSelect"

    def get_event_triggers(self) -> Dict[str, Any]:
        return {
            EventTriggers.ON_CHANGE: lambda _e, value: [value],
        }

rx.download special event

The new download event prompts the frontend browser for file download.

It can be used directly as an event trigger:

rx.button("Download file", on_click=rx.download("/uri/for/file.extension", "target_file.extension")

Or it can be yielded from a backend event handler:

def export_data(self):
    ...
    # do export logic here and write to filepath
    # then
    yield rx.download(filepath, filename)

Register Serializers for Custom Types

A one-arg callable in a Reflex app or component module with @rx.serializer decorator will be considered a serializer for the type of its argument. This allows arbitrary types used on the backend to be accessed on the frontend, as long as there is a serializer defined that returns a JSON serializable value.

For example, the following code is used to serialize plotly Figure objects.

import json
from plotly.graph_objects import Figure
from plotly.io import to_json

@rx.serializer
def serialize_figure(figure: Figure) -> list:
    return json.loads(str(to_json(figure)))["data"]

Background Task Event Handlers that do not block other Events

An async EventHandler function in a State that is decorated with @rx.background is considered a "Background Task". When triggered by the frontend or chained from another event handler, it will spawn a long running task that will NOT block other EventHandlers from running.

There are three main differences from a normal EventHandler to be aware of:

  • Background Task must be async
  • Background Task cannot directly modify state values and state values may be stale if other events have modified the state since the task started running.
    • Only read or write state vars inside an async with self context block, where exclusive access to the latest state is guaranteed.
  • Background Task cannot be directly called from another event handler.
    • Must yield or return the background task to chain it from another handler.
class State(rx.State):

    counter: int = 0

    @rx.background
    async def bg_task(self):
        for ix in range(10):
            async with self:
                # state mutation is only allowed inside context block
                self.counter += 1

            # await long operations outside the context to avoid blocking
            await asyncio.sleep(0.5)

Full documentation for this feature is still being developed. Please post comments regarding background tasks on the discussion thread.

  • rx.background and StateManager.modify_state provides safe exclusive access to state by @masenf in #1676

Improvements

Support Reactivity for rx.Base fields

Modifying fields on an rx.Base instance will trigger updates in the state without having to reassign them. This also applies when working with fields that are container types such as list and dict.

  • Reassign state Var when fields on a Base instance change by @masenf in #1748

Better Error Messages

Usability

Bug Fixes

  • added check to remove local import starting from . by @wassafshahzad in #1807
  • exec: print the URL, not the address the server binds to by @masenf in #1846

Minor Changes and Fixups

New Contributors

Full Changelog: v0.2.7...v0.2.8

v0.2.7

07 Sep 23:16
47d789e
Compare
Choose a tag to compare

πŸ™Β Thanks to our supportive community and helpful contributors! πŸ’ͺ

Breaking Changes

Default Websocket Endpoint is now /_event #1542

Upload endpoint also moved to /_upload.

Any reverse proxy configurations that were explicitly forwarding /event and /upload to the backend server should be updated to use the new endpoints.

App kwarg connect_error_component is removed.

Use overlay_component instead. (#1379)

New Features

Client-side Storage integrated with State #1629

  • Allow rx.LocalStorage and rx.Cookie type vars in a State class that are automatically persisted in the client browser when modified on the backend.
  • These values can be used in frontend or backend code just like any other state Var.
class State(rx.State):
	my_token: rx.LocalStorage = ""
  my_hour_cookie: rx.Cookie = rx.Cookie("initial", max_age=3600)

  def set_token(self):
    self.my_token = str(uuid.uuid4())

  def update_cookie(self):
    if self.my_hour_cookie == "initial":
      self.my_hour_cookie = "updated"

Implement on_mount and on_unmount for all components #1636

These new event handlers, present on all components, tie into React’s useEffect hook and are used to trigger backend events needed to initialize a component when it loaded in a page.

Note: on_mount will fire twice in dev mode due to the use of React’s StrictMode.

Note: on_mount will not fire for page navigation events between different params of the same dynamic route, since the page itself does not get reloaded so no remount occurs. For navigation events, see on_load argument of app.add_page.

FNM is now used to install nodejs on POSIX platforms

by @ElijahAhianyo in #1606 #1701

frontend_packages are automatically determined #1607

  • frontend_packages are inferred based on the library prop of a wrapped component, instead of having to specify them manually in the rxconfig.py file.
  • The library prop may now include a version pin, like **library =** "gridjs-react@^6.0.1"
  • The package.json list of frontend dependencies only includes components that are actually used in the app, which decreases bundle size.
  • To include additional dependencies used by a component, specify them in the new lib_dependencies prop of the wrapped component.

Per-component prop autocompletion for IDEs #1708

Generated .pyi files provide better function signatures for component create methods, enumerating most recognized props.

Further enhancements will be supplied in a future release to include per-prop documentation and improved signatures for event handlers.

Support Breakpoints in VSCode and PyCharm #1653

  • Breakpoints set in the IDE will be respected when running the project in dev mode. See DEBUGGING.md for an example.

Expose basePath configuration option #1724

Support running multiple reflex apps from the same domain by changing the basePath prefix that the frontend uses (by @nevdelap).

Improvements

  • Validate component children by @ElijahAhianyo in #1647
  • Refactor zipping in reflex export by @martinxu9 in #1668
  • Avoid leaking secrets in log files and on the console.
    • fix:issue-1667;added if condition check to not echo DB_URL by @shashank40 in #1681
  • Automatically display a Modal when the backend is unable to connect.
    • ConnectionModal and ConnectionBanner cleanup by @masenf in #1379
  • Add contains, reverse operations for Var by @martinxu9 in #1679
  • Add special var for upload: clear_selected_files by @martinxu9 in #1703
  • Support automatic serialization of date, datetime, time, and timedelta Vars in a State class.
  • Raise TypeError when attempting to incorrectly use a state Var in a bool or iter context.
    • Var: __**bool__** and __**iter__** always raise a TypeError by @masenf in #1750
  • Allow dynamic routes to work with static hosting (github pages, netlify, s3, etc)
    • Client-side Routing (404 redirect) by @masenf in #1695
    • Fix browser error when navigating to missing route and custom 404 page is not used.
    • No need to run the frontend nodejs process, see updated docker-example.

Bug Fixes

  • ReflexList: reassign field on insert by @masenf in #1652
  • Allow event handlers in parent state to be directly called from child state.
    • state: _init_event_handlers recursively by @masenf in #1640
  • Allow rx.form to work with debounce inputs
    • [REF-526] debounce_input should respect child ref by @masenf in #1717
  • Track var dependencies in comprehensions and nested functions by @masenf in #1728
  • Proper serialization for chained Event payloads by @masenf in #1725

Minor Changes and Fixups

New Contributors

Full Changelog: v0.2.6...v0.2.7

v0.2.6

23 Aug 22:40
57855f5
Compare
Choose a tag to compare

A quick follow-up release to fix issues discovered and reported by our thriving community on Discord. πŸ’ͺ

Fix Regressions

Ensure non-sqlite databases can be used #1661

  • model: only pass "check_same_thread" arg for sqlite database by @masenf in #1662

Block problematic upstream package python-engineio-4.6.0 #1658

  • pyproject.toml: requires python-engineio!=4.6.0 by @masenf in #1663

Other Changes

New Contributors

Full Changelog: v0.2.5...v0.2.6

v0.2.5

21 Aug 22:10
e017f31
Compare
Choose a tag to compare

πŸ’ͺ Thanks to our amazing users and contributors!! πŸ™Œ 🐍

Known Regressions

  • non-sqlite database access is not working #1661

Breaking Changes

Chained event handlers from return / yield must always be referenced from the State class, NOT the instance

class State(rx.State):
    def handlerA(self):
        ...

    def handlerB(self):
        return self.handlerA()  # ❌ Will raise TypeError now!

    def handlerC(self):
        return State.handlerA()  # βœ… Always reference chained handlers by class

The exception will look like TypeError: Your handler State.handlerB must only return/yield: None, Events or other EventHandlers referenced by their class (not using self) and will occur when the handler is called, not at compile time.

Removal of Config knobs

  • admin_dash - configure the admin dashboard via rx.App instead
  • backend_transports - all connections will use websocket
  • cors_credentials
  • db_config - use db_url instead
  • env - specify the run environment via CLI flags to reflex run --env dev|prod
  • env_path - reading environment variables from a file is no longer supported (suggest use of docker-compose or simply source the env file before running reflex)
  • override_os_envs - os environment variables will always take precedence
  • polling_max_http_buffer_size - all connections will use websocket

New Features

Support f-string formatting of State vars

Frontend rendering functions can now make use of f"built in {State.value}" style formatting, instead of + concatenation.

Node.js is automatically installed on Windows (non-WSL)

Using the cross-platform fnm tool to facilitate automatic installation of node runtime on native windows platform, where previously a manual install was needed.

POSIX support for fnm to replace nvm is coming soon.

Display system and environment information with --loglevel debug

For easier bug reporting and investigations, all relevant platform info, config, and tools used by Reflex will be logged in debug mode.

rx.selected_files Var exposes files selected by the rx.upload component

This new Var can be rendered as a frontend component:

rx.foreach(
    rx.selected_files,
    rx.text,
)

Improvements

Frontend performance boost

Refactoring the main frontend event loop reduces event handling and rendering time by 3x.

Refactored Config class

Simplify configuration knobs and recognize all configuration values set as environment variables.

rx.form now works with more form components

Including rx.pin_input, rx.number_input, and rx.range_slider

More flexible container serialization inside State classes

  • set is now supported as a Var type
  • Recursive serialization now allows for list, tuple, and set of PIL image, plotly plots, and pandas dataframes.

Use β€œtrailingSlash” mode to better support static site hosting

When exporting a site via reflex export, an index.html file will be created inside a directory for each static route, which makes hosting via s3, github pages, netlify, and others simpler by not requiring a β€œtry_files” rule or rewrites.

docker-example is simplified and extended

The main Dockerfile is simpler and there is now a compose.yaml and Caddy.Dockerfile which can be used to deploy a reflex app with automatic TLS support.

Other Improvements

  • Expose debounce_timeout prop on rx.input and rx.text_area for tuning fully-controlled input behavior on large sites.
  • Ignore *.db and files in default .gitignore template
  • NoSSRComponent supports components using either named or default exports.

Bug Fixes

  • Flex wrap and direction props accept list of values, for use at different responsive breakpoints.
  • Can specify on_load when defining a custom 404 page.
  • Raise useful exception when a user-defined State var shadows an internal name.
  • BUN_PATH is respected again (regression from 0.2.3)
  • Var operations like to_string, and, and or return a new Var with the correct type_ set.
  • Passing a dict as a prop where the values contain double quotes is no longer an error. (Fix rx.html component where content contains double quotes)

Other Changes

New Contributors

Full Changelog: v0.2.4...v0.2.5

v0.2.4

09 Aug 04:17
9f7a7a1
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.2.3...v0.2.4

v0.2.3

31 Jul 03:53
f01eff5
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v0.2.2...v0.2.3

v0.2.2

20 Jul 22:28
723105d
Compare
Choose a tag to compare

Small release fixing a bug in the render of pc.foreach.

What's Changed

New Contributors

Full Changelog: v0.2.1...v0.2.2

v0.2.1

19 Jul 21:01
bfec196
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v0.2.0...v0.2.1

v0.2.0

13 Jul 03:06
8cb12c7
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v0.1.34...v0.2.0