Skip to content

Migrate to Reflex plugins and remove deprecated rx.Model usage#322

Merged
masenf merged 52 commits into
mainfrom
claude/fix-reflex-deprecations-WBIBJ
Jun 8, 2026
Merged

Migrate to Reflex plugins and remove deprecated rx.Model usage#322
masenf merged 52 commits into
mainfrom
claude/fix-reflex-deprecations-WBIBJ

Conversation

@masenf

@masenf masenf commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR modernizes the Reflex example applications by migrating theme configuration to the new plugin system and replacing deprecated rx.Model with sqlmodel.SQLModel. It also adds explicit event handlers for state mutations and removes unused dependencies.

Key Changes

Theme Configuration Migration

  • Moved theme configuration from app instantiation to rxconfig.py using rx.plugins.RadixThemesPlugin()
  • Removed inline theme= parameters from rx.App() constructors across all example apps
  • Updated all rxconfig.py files to use the new plugin-based theme system with appropriate accent colors per app

Model System Updates

  • Replaced all rx.Model base classes with sqlmodel.SQLModel in database models
  • Added explicit id: int | None = Field(default=None, primary_key=True) fields to all model classes
  • Updated imports to use sqlmodel directly instead of through reflex
  • Fixed form_designer migration code to use sqlmodel.SQLModel.metadata.create_all() instead of deprecated rx.Model.migrate()

Event Handler Additions

  • Added explicit @rx.event decorated setter methods for state mutations in:
    • clock: set_zone()
    • translator: set_text(), set_lang()
    • twitter/auth: set_username(), set_password(), set_confirm_password()
    • twitter/home: set_tweet(), set_friend()
    • basic_crud: set_url_query(), set_body()
    • form_designer: set_options_editor_open()
    • github_stats: set_username()
    • local_component: set_who()
    • traversal: set_option()

Component Updates

  • Replaced reflex_chakra circular progress components with native Reflex components in lorem_stream and quiz
  • Updated translator to use rx.PropsBase instead of rx.Base
  • Removed unused reflex_chakra imports and dependencies from requirements.txt

Code Cleanup

  • Removed unused imports (e.g., from reflex.components.radix.themes import theme)
  • Removed tailwind=None configuration in favor of plugin-based setup
  • Updated type hints in data_visualisation to use generic type instead of rx.Model

https://claude.ai/code/session_01Y1Tf2L28wnta7Tu9ZeKKgB

claude added 30 commits May 12, 2026 15:35
…_open setter, move theme to RadixThemesPlugin

The remaining rx.Model DeprecationWarning originates from reflex_local_auth.LocalUser, which is external to this repo.
Munge requirements.txt in-place so that the existing 'reflex' (or
'reflex[db]') pin is rewritten to use REFLEX_DEP as a direct reference.
This preserves extras such as [db] that the app needs to function,
instead of installing a stock reflex alongside the requirements file.
This app uses rx.session, which depends on the optional [db] extra and
the (previously default) sqlite db_url.
This app uses rx.session, which depends on the optional [db] extra and
the (previously default) sqlite db_url.
This app uses rx.session, which depends on the optional [db] extra.
db_url is already configured via DATABASE_URL env (or sqlite default).
claude and others added 22 commits May 12, 2026 20:35
This app uses rx.session, which depends on the optional [db] extra.
db_url is already configured.
This app uses rx.session, which depends on the optional [db] extra and
the (previously default) sqlite db_url.
The previous approach only pinned the top-level reflex package to the
git URL, so pip still resolved the monorepo's subpackages (reflex-base,
reflex-components-*, etc.) from PyPI. Check out the reflex repo to a
sibling directory and rewrite the requirements pin to a file:// URL of
that checkout so pip can pull the subpackages from the same source.

The workflow_dispatch input is renamed to reflex_ref since we now drive
the install from a git ref rather than a pip spec.
reflex uses dynamic versioning derived from git tags, so a shallow
checkout without tags would fail to compute the package version.
uv understands workspace source declarations in reflex's pyproject.toml,
which pip ignores. This should resolve reflex's subpackages from the
local checkout instead of pulling them from PyPI.
…al_auth

reflex_local_auth.LocalUser still subclasses the deprecated rx.Model,
which emits a console.deprecate() warning at import time. Until the
upstream package migrates to SQLModel, monkey-patch console.deprecate
to silence that specific feature name.
0.5.0 drops rx.Model in favor of SQLModel, removing the lingering
DeprecationWarning that previously came from the upstream LocalUser.
Switches to the shared Microsoft consumers tenant
(9188040d-6c67-4c5b-b112-36a304b66dad) and a public example client id
so the app's OIDC discovery succeeds without a private tenant.
The auto-generated set_* setter no longer exists in current Reflex;
provide an explicit @rx.event handler.
rx.Model.select was removed alongside rx.Model itself; switch to the
standard sqlmodel.select(Model).where(...) form.
RadixThemesPlugin was introduced in 0.9.2; apps whose rxconfig.py
references it need the matching minimum version.
AppHarness no longer exposes get_state(); the frontend already asserts
the same count values via poll_for_content, so the backend-state checks
were redundant.
Polling for the session-storage token confirms the frontend has
connected to the backend before the test exercises the UI.
rx.Model.select was removed alongside rx.Model itself; switch the Form
and Response queries to the standard sqlmodel.select(Model).where(...)
form to match the tests.
uv pip install understands workspace declarations in a git-fetched
reflex source dist, so we no longer need a sibling checkout of
reflex-dev/reflex to pull in the monorepo subpackages.
Replaces the hand-rolled SQLModel.metadata.create_all(get_engine())
with the public helper. Also sets alembic's path_separator=os to
silence the unrelated alembic DeprecationWarning that the helper
surfaces.
@masenf masenf marked this pull request as ready for review June 8, 2026 22:49
@greptile-apps

greptile-apps Bot commented Jun 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR modernizes 20+ Reflex example apps for compatibility with Reflex 0.9 by migrating rx.Modelsqlmodel.SQLModel, moving theme config from rx.App() arguments to rxconfig.py plugins, and adding explicit @rx.event setter methods across multiple state classes. It also replaces deprecated reflex_chakra circular-progress components with native Reflex equivalents and upgrades the CI workflow to install reflex from a local checkout via uv.

  • Model migration: All rx.Model table classes across basic_crud, chat_v2, data_visualisation, form-designer, twitter, and others now extend sqlmodel.SQLModel directly, with explicit id: int | None = Field(default=None, primary_key=True) fields added to each.
  • Event handler additions: Explicit @rx.event setters (set_zone, set_text, set_lang, set_tweet, set_friend, set_username, set_password, etc.) are added across clock, translator, twitter, basic_crud, form-designer, github-stats, local-component, and traversal.
  • CI overhaul: The export-check workflow now checks out the reflex source repo alongside the examples, rewrites requirements.txt to use a file:// reference to the local clone, and installs with uv pip install.

Confidence Score: 3/5

Safe to merge for the broad theme/model/event-handler changes, but the form-designer startup path has an unverified call that could silently fail to create tables on the hosting service.

Nearly all changes are straightforward mechanical substitutions with low risk. The one outlier is rx.model.migrate() at the end of form-designer/form_designer/form_designer.py: the PR description says this should be sqlmodel.SQLModel.metadata.create_all(), but the code calls a module-level attribute that may or may not exist in reflex 0.9. If it does not exist, the form-designer app will fail to auto-create its tables on any hosting environment that does not run alembic migrations.

form-designer/form_designer/form_designer.py — specifically the rx.model.migrate() call at the bottom that may not be a valid API in reflex 0.9

Important Files Changed

Filename Overview
form-designer/form_designer/form_designer.py Migration call changed from rx.Model.migrate() to rx.model.migrate() — likely incorrect; PR description says use sqlmodel.SQLModel.metadata.create_all() instead
traversal/traversal/traversal.py set_option event handler added; walls class attribute placed immediately after method body with no blank line separator
azure_auth/azure_auth/auth/core.py Azure AD client_id and tenant_id replaced with new hardcoded values; new tenant is MS consumer-accounts tenant but client_id remains a concrete UUID in source
.github/workflows/check_export.yml Refactored to check out reflex repo locally and rewrite requirements.txt with file:// references; switches from pip to uv — logic looks correct
form-designer/form_designer/models.py All models migrated from rx.Model to sqlmodel.SQLModel with explicit id primary key fields added
twitter/twitter/db_model.py User and Tweet models get explicit id PKs; Follows correctly omits id since it uses composite string PKs
counter/tests/test_counter.py Removed backend state assertions; only UI-side content polling retained — reduces coverage but tests compile and run
form-designer/tests/conftest.py Updated LocalUser query to use sqlmodel.select() instead of the deprecated Model.select() class method

Reviews (1): Last reviewed commit: "Revert "check_export: drop local reflex ..." | Re-trigger Greptile

Comment thread form-designer/form_designer/form_designer.py
Comment thread traversal/traversal/traversal.py
Comment thread azure_auth/azure_auth/auth/core.py
@masenf masenf merged commit ebe19ff into main Jun 8, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants