reflex 0.4.6a4__py3-none-any.whl → 0.4.7a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of reflex might be problematic. Click here for more details.

Files changed (68) hide show
  1. reflex/.templates/apps/blank/code/blank.py +1 -0
  2. reflex/.templates/jinja/custom_components/pyproject.toml.jinja2 +1 -1
  3. reflex/.templates/jinja/custom_components/src.py.jinja2 +8 -8
  4. reflex/.templates/jinja/web/pages/index.js.jinja2 +0 -4
  5. reflex/.templates/jinja/web/pages/stateful_component.js.jinja2 +2 -6
  6. reflex/.templates/web/utils/state.js +6 -1
  7. reflex/__init__.py +2 -0
  8. reflex/__init__.pyi +2 -0
  9. reflex/app.py +12 -16
  10. reflex/app.pyi +2 -0
  11. reflex/compiler/compiler.py +10 -11
  12. reflex/compiler/utils.py +3 -3
  13. reflex/components/chakra/forms/pininput.py +2 -1
  14. reflex/components/component.py +71 -104
  15. reflex/components/core/banner.py +1 -1
  16. reflex/components/core/upload.py +2 -1
  17. reflex/components/datadisplay/__init__.py +1 -0
  18. reflex/components/datadisplay/logo.py +49 -0
  19. reflex/components/el/elements/forms.py +7 -4
  20. reflex/components/el/elements/forms.pyi +0 -1
  21. reflex/components/lucide/icon.py +3 -2
  22. reflex/components/lucide/icon.pyi +2 -2
  23. reflex/components/markdown/markdown.py +10 -6
  24. reflex/components/markdown/markdown.pyi +0 -3
  25. reflex/components/radix/themes/components/select.py +10 -3
  26. reflex/config.py +1 -1
  27. reflex/config.pyi +1 -1
  28. reflex/constants/base.py +4 -5
  29. reflex/constants/base.pyi +94 -0
  30. reflex/constants/compiler.py +8 -0
  31. reflex/custom_components/custom_components.py +1 -1
  32. reflex/experimental/__init__.py +14 -0
  33. reflex/experimental/hooks.py +75 -0
  34. reflex/page.py +1 -1
  35. reflex/reflex.py +18 -32
  36. reflex/style.py +4 -4
  37. reflex/testing.py +1 -1
  38. reflex/utils/console.py +6 -4
  39. reflex/utils/exec.py +17 -1
  40. reflex/utils/export.py +0 -3
  41. reflex/utils/prerequisites.py +239 -43
  42. reflex/utils/processes.py +6 -1
  43. reflex/utils/telemetry.py +14 -2
  44. reflex/vars.py +6 -6
  45. reflex/vars.pyi +2 -1
  46. {reflex-0.4.6a4.dist-info → reflex-0.4.7a1.dist-info}/METADATA +15 -10
  47. {reflex-0.4.6a4.dist-info → reflex-0.4.7a1.dist-info}/RECORD +50 -64
  48. {reflex-0.4.6a4.dist-info → reflex-0.4.7a1.dist-info}/WHEEL +1 -1
  49. reflex/.templates/apps/sidebar/README.md +0 -69
  50. reflex/.templates/apps/sidebar/assets/favicon.ico +0 -0
  51. reflex/.templates/apps/sidebar/assets/github.svg +0 -10
  52. reflex/.templates/apps/sidebar/assets/logo.svg +0 -68
  53. reflex/.templates/apps/sidebar/assets/paneleft.svg +0 -13
  54. reflex/.templates/apps/sidebar/assets/reflex_black.svg +0 -37
  55. reflex/.templates/apps/sidebar/assets/reflex_white.svg +0 -8
  56. reflex/.templates/apps/sidebar/code/__init__.py +0 -1
  57. reflex/.templates/apps/sidebar/code/components/__init__.py +0 -0
  58. reflex/.templates/apps/sidebar/code/components/sidebar.py +0 -152
  59. reflex/.templates/apps/sidebar/code/pages/__init__.py +0 -3
  60. reflex/.templates/apps/sidebar/code/pages/dashboard.py +0 -22
  61. reflex/.templates/apps/sidebar/code/pages/index.py +0 -18
  62. reflex/.templates/apps/sidebar/code/pages/settings.py +0 -61
  63. reflex/.templates/apps/sidebar/code/sidebar.py +0 -16
  64. reflex/.templates/apps/sidebar/code/styles.py +0 -60
  65. reflex/.templates/apps/sidebar/code/templates/__init__.py +0 -1
  66. reflex/.templates/apps/sidebar/code/templates/template.py +0 -145
  67. {reflex-0.4.6a4.dist-info → reflex-0.4.7a1.dist-info}/LICENSE +0 -0
  68. {reflex-0.4.6a4.dist-info → reflex-0.4.7a1.dist-info}/entry_points.txt +0 -0
@@ -133,7 +133,7 @@ class Markdown(Component):
133
133
  **props,
134
134
  )
135
135
 
136
- def get_custom_components(
136
+ def _get_all_custom_components(
137
137
  self, seen: set[str] | None = None
138
138
  ) -> set[CustomComponent]:
139
139
  """Get all the custom components used by the component.
@@ -144,11 +144,13 @@ class Markdown(Component):
144
144
  Returns:
145
145
  The set of custom components.
146
146
  """
147
- custom_components = super().get_custom_components(seen=seen)
147
+ custom_components = super()._get_all_custom_components(seen=seen)
148
148
 
149
149
  # Get the custom components for each tag.
150
150
  for component in self.component_map.values():
151
- custom_components |= component(_MOCK_ARG).get_custom_components(seen=seen)
151
+ custom_components |= component(_MOCK_ARG)._get_all_custom_components(
152
+ seen=seen
153
+ )
152
154
 
153
155
  return custom_components
154
156
 
@@ -183,7 +185,9 @@ class Markdown(Component):
183
185
 
184
186
  # Get the imports for each component.
185
187
  for component in self.component_map.values():
186
- imports = utils.merge_imports(imports, component(_MOCK_ARG).get_imports())
188
+ imports = utils.merge_imports(
189
+ imports, component(_MOCK_ARG)._get_all_imports()
190
+ )
187
191
 
188
192
  # Get the imports for the code components.
189
193
  imports = utils.merge_imports(
@@ -293,8 +297,8 @@ class Markdown(Component):
293
297
  hooks = set()
294
298
  for _component in self.component_map.values():
295
299
  comp = _component(_MOCK_ARG)
296
- hooks |= comp.get_hooks_internal()
297
- hooks |= comp.get_hooks()
300
+ hooks.update(comp._get_all_hooks_internal())
301
+ hooks.update(comp._get_all_hooks())
298
302
  formatted_hooks = "\n".join(hooks)
299
303
  return f"""
300
304
  function {self._get_component_map_name()} () {{
@@ -123,9 +123,6 @@ class Markdown(Component):
123
123
  The markdown component.
124
124
  """
125
125
  ...
126
- def get_custom_components(
127
- self, seen: set[str] | None = None
128
- ) -> set[CustomComponent]: ...
129
126
  def get_component(self, tag: str, **props) -> Component: ...
130
127
  def format_component(self, tag: str, **props) -> str: ...
131
128
  def format_component_map(self) -> dict[str, str]: ...
@@ -198,6 +198,15 @@ class HighLevelSelect(SelectRoot):
198
198
  Returns:
199
199
  The select component.
200
200
  """
201
+ trigger_prop_list = [
202
+ "placeholder",
203
+ "variant",
204
+ "radius",
205
+ "width",
206
+ "flex_shrink",
207
+ "custom_attrs",
208
+ ]
209
+
201
210
  content_props = {
202
211
  prop: props.pop(prop)
203
212
  for prop in ["high_contrast", "position"]
@@ -205,9 +214,7 @@ class HighLevelSelect(SelectRoot):
205
214
  }
206
215
 
207
216
  trigger_props = {
208
- prop: props.pop(prop)
209
- for prop in ["placeholder", "variant", "radius", "width", "flex_shrink"]
210
- if prop in props
217
+ prop: props.pop(prop) for prop in trigger_prop_list if prop in props
211
218
  }
212
219
 
213
220
  color_scheme = props.pop("color_scheme", None)
reflex/config.py CHANGED
@@ -299,7 +299,7 @@ class Config(Base):
299
299
 
300
300
  return updated_values
301
301
 
302
- def get_event_namespace(self) -> str | None:
302
+ def get_event_namespace(self) -> str:
303
303
  """Get the websocket event namespace.
304
304
 
305
305
  Returns:
reflex/config.pyi CHANGED
@@ -104,7 +104,7 @@ class Config(Base):
104
104
  @staticmethod
105
105
  def check_deprecated_values(**kwargs) -> None: ...
106
106
  def update_from_env(self) -> None: ...
107
- def get_event_namespace(self) -> str | None: ...
107
+ def get_event_namespace(self) -> str: ...
108
108
  def _set_persistent(self, **kwargs) -> None: ...
109
109
 
110
110
  def get_config(reload: bool = ...) -> Config: ...
reflex/constants/base.py CHANGED
@@ -88,12 +88,11 @@ class ReflexHostingCLI(SimpleNamespace):
88
88
  class Templates(SimpleNamespace):
89
89
  """Constants related to Templates."""
90
90
 
91
- # Dynamically get the enum values from the .templates folder
92
- template_dir = os.path.join(Reflex.ROOT_DIR, Reflex.MODULE_NAME, ".templates/apps")
93
- template_dirs = next(os.walk(template_dir))[1]
91
+ # The route on Reflex backend to query which templates are available and their URLs.
92
+ APP_TEMPLATES_ROUTE = "/app-templates"
94
93
 
95
- # Create an enum value for each directory in the .templates folder
96
- Kind = Enum("Kind", {template.upper(): template for template in template_dirs})
94
+ # The default template
95
+ DEFAULT = "blank"
97
96
 
98
97
  class Dirs(SimpleNamespace):
99
98
  """Folders used by the template system of Reflex."""
@@ -0,0 +1,94 @@
1
+ """Stub file for reflex/constants/base.py"""
2
+ # ------------------- DO NOT EDIT ----------------------
3
+ # This file was generated by `reflex/utils/pyi_generator.py`!
4
+ # ------------------------------------------------------
5
+
6
+ from typing import Any, Dict, Literal, Optional, Union, overload
7
+ from reflex.vars import Var, BaseVar, ComputedVar
8
+ from reflex.event import EventChain, EventHandler, EventSpec
9
+ from reflex.style import Style
10
+ import os
11
+ import platform
12
+ from enum import Enum
13
+ from importlib import metadata
14
+ from types import SimpleNamespace
15
+ from platformdirs import PlatformDirs
16
+
17
+ IS_WINDOWS = platform.system() == "Windows"
18
+
19
+ class Dirs(SimpleNamespace):
20
+ WEB = ".web"
21
+ APP_ASSETS = "assets"
22
+ UTILS = "utils"
23
+ STATIC = "_static"
24
+ STATE_PATH = "/".join([UTILS, "state"])
25
+ COMPONENTS_PATH = "/".join([UTILS, "components"])
26
+ CONTEXTS_PATH = "/".join([UTILS, "context"])
27
+ WEB_PAGES = os.path.join(WEB, "pages")
28
+ WEB_STATIC = os.path.join(WEB, STATIC)
29
+ WEB_UTILS = os.path.join(WEB, UTILS)
30
+ WEB_ASSETS = os.path.join(WEB, "public")
31
+ ENV_JSON = os.path.join(WEB, "env.json")
32
+ REFLEX_JSON = os.path.join(WEB, "reflex.json")
33
+ POSTCSS_JS = os.path.join(WEB, "postcss.config.js")
34
+
35
+ class Reflex(SimpleNamespace):
36
+ MODULE_NAME = "reflex"
37
+ VERSION = metadata.version(MODULE_NAME)
38
+ JSON = os.path.join(Dirs.WEB, "reflex.json")
39
+ _dir = os.environ.get("REFLEX_DIR", "")
40
+ DIR = _dir or PlatformDirs(MODULE_NAME, False).user_data_dir
41
+ ROOT_DIR = os.path.dirname(
42
+ os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
43
+ )
44
+
45
+ class ReflexHostingCLI(SimpleNamespace):
46
+ MODULE_NAME = "reflex-hosting-cli"
47
+
48
+ class Templates(SimpleNamespace):
49
+ APP_TEMPLATES_ROUTE = "/app-templates"
50
+ DEFAULT = "blank"
51
+
52
+ class Dirs(SimpleNamespace):
53
+ BASE = os.path.join(Reflex.ROOT_DIR, Reflex.MODULE_NAME, ".templates")
54
+ WEB_TEMPLATE = os.path.join(BASE, "web")
55
+ JINJA_TEMPLATE = os.path.join(BASE, "jinja")
56
+ CODE = "code"
57
+
58
+ class Next(SimpleNamespace):
59
+ CONFIG_FILE = "next.config.js"
60
+ SITEMAP_CONFIG_FILE = os.path.join(Dirs.WEB, "next-sitemap.config.js")
61
+ NODE_MODULES = "node_modules"
62
+ PACKAGE_LOCK = "package-lock.json"
63
+ FRONTEND_LISTENING_REGEX = "Local:[\\s]+(.*)"
64
+
65
+ class ColorMode(SimpleNamespace):
66
+ NAME = "colorMode"
67
+ USE = "useColorMode"
68
+ TOGGLE = "toggleColorMode"
69
+
70
+ class Env(str, Enum):
71
+ DEV = "dev"
72
+ PROD = "prod"
73
+
74
+ class LogLevel(str, Enum):
75
+ DEBUG = "debug"
76
+ INFO = "info"
77
+ WARNING = "warning"
78
+ ERROR = "error"
79
+ CRITICAL = "critical"
80
+
81
+ POLLING_MAX_HTTP_BUFFER_SIZE = 1000 * 1000
82
+
83
+ class Ping(SimpleNamespace):
84
+ INTERVAL = 25
85
+ TIMEOUT = 120
86
+
87
+ COOKIES = "cookies"
88
+ LOCAL_STORAGE = "local_storage"
89
+ SKIP_COMPILE_ENV_VAR = "__REFLEX_SKIP_COMPILE"
90
+ ENV_MODE_ENV_VAR = "REFLEX_ENV_MODE"
91
+ PYTEST_CURRENT_TEST = "PYTEST_CURRENT_TEST"
92
+ RELOAD_CONFIG = "__REFLEX_RELOAD_CONFIG"
93
+ REFLEX_VAR_OPENING_TAG = "<reflex.Var>"
94
+ REFLEX_VAR_CLOSING_TAG = "</reflex.Var>"
@@ -111,6 +111,14 @@ class Hooks(SimpleNamespace):
111
111
  """Common sets of hook declarations."""
112
112
 
113
113
  EVENTS = f"const [{CompileVars.ADD_EVENTS}, {CompileVars.CONNECT_ERROR}] = useContext(EventLoopContext);"
114
+ AUTOFOCUS = """
115
+ // Set focus to the specified element.
116
+ const focusRef = useRef(null)
117
+ useEffect(() => {
118
+ if (focusRef.current) {
119
+ focusRef.current.focus();
120
+ }
121
+ })"""
114
122
 
115
123
 
116
124
  class MemoizationDisposition(enum.Enum):
@@ -145,7 +145,7 @@ def _populate_demo_app(name_variants: NameVariants):
145
145
 
146
146
  with set_directory(demo_app_dir):
147
147
  # We start with the blank template as basis.
148
- _init(name=demo_app_name, template=constants.Templates.Kind.BLANK)
148
+ _init(name=demo_app_name, template=constants.Templates.DEFAULT)
149
149
  # Then overwrite the app source file with the one we want for testing custom components.
150
150
  # This source file is rendered using jinja template file.
151
151
  with open(f"{demo_app_name}/{demo_app_name}.py", "w") as f:
@@ -0,0 +1,14 @@
1
+ """Namespace for experimental features."""
2
+
3
+ from types import SimpleNamespace
4
+
5
+ from ..utils.console import warn
6
+ from . import hooks as hooks
7
+
8
+ warn(
9
+ "`rx._x` contains experimental features and might be removed at any time in the future .",
10
+ )
11
+
12
+ _x = SimpleNamespace(
13
+ hooks=hooks,
14
+ )
@@ -0,0 +1,75 @@
1
+ """Add standard Hooks wrapper for React."""
2
+
3
+ from reflex.utils.imports import ImportVar
4
+ from reflex.vars import Var, VarData
5
+
6
+
7
+ def _add_react_import(v: Var | None, tags: str | list):
8
+ if v is None:
9
+ return
10
+
11
+ if isinstance(tags, str):
12
+ tags = [tags]
13
+
14
+ v._var_data = VarData( # type: ignore
15
+ imports={"react": [ImportVar(tag=tag) for tag in tags]},
16
+ )
17
+
18
+
19
+ def const(name, value) -> Var | None:
20
+ """Create a constant Var.
21
+
22
+ Args:
23
+ name: The name of the constant.
24
+ value: The value of the constant.
25
+
26
+ Returns:
27
+ The constant Var.
28
+ """
29
+ return Var.create(f"const {name} = {value}")
30
+
31
+
32
+ def useCallback(func, deps) -> Var | None:
33
+ """Create a useCallback hook with a function and dependencies.
34
+
35
+ Args:
36
+ func: The function to wrap.
37
+ deps: The dependencies of the function.
38
+
39
+ Returns:
40
+ The useCallback hook.
41
+ """
42
+ if deps:
43
+ v = Var.create(f"useCallback({func}, {deps})")
44
+ else:
45
+ v = Var.create(f"useCallback({func})")
46
+ _add_react_import(v, "useCallback")
47
+ return v
48
+
49
+
50
+ def useContext(context) -> Var | None:
51
+ """Create a useContext hook with a context.
52
+
53
+ Args:
54
+ context: The context to use.
55
+
56
+ Returns:
57
+ The useContext hook.
58
+ """
59
+ v = Var.create(f"useContext({context})")
60
+ _add_react_import(v, "useContext")
61
+ return v
62
+
63
+
64
+ def useRef(default) -> Var | None:
65
+ """Create a useRef hook with a default value.
66
+
67
+ Args:
68
+ default: The default value of the ref.
69
+
70
+ Returns:
71
+ The useRef hook.
72
+ """
73
+ v = Var.create(f"useRef({default})")
74
+ _add_react_import(v, "useRef")
75
+ return v
reflex/page.py CHANGED
@@ -30,7 +30,7 @@ def page(
30
30
  title: The title of the page.
31
31
  image: The favicon of the page.
32
32
  description: The description of the page.
33
- meta: Additionnal meta to add to the page.
33
+ meta: Additional meta to add to the page.
34
34
  on_load: The event handler(s) called when the page load.
35
35
  script_tags: scripts to attach to the page
36
36
 
reflex/reflex.py CHANGED
@@ -63,7 +63,7 @@ def main(
63
63
 
64
64
  def _init(
65
65
  name: str,
66
- template: constants.Templates.Kind | None = constants.Templates.Kind.BLANK,
66
+ template: str | None = None,
67
67
  loglevel: constants.LogLevel = config.loglevel,
68
68
  ):
69
69
  """Initialize a new Reflex app in the given directory."""
@@ -79,31 +79,20 @@ def _init(
79
79
  app_name = prerequisites.validate_app_name(name)
80
80
  console.rule(f"[bold]Initializing {app_name}")
81
81
 
82
+ # Check prerequisites.
82
83
  prerequisites.check_latest_package_version(constants.Reflex.MODULE_NAME)
83
-
84
84
  prerequisites.initialize_reflex_user_directory()
85
-
86
85
  prerequisites.ensure_reflex_installation_id()
87
86
 
88
87
  # When upgrading to 0.4, show migration instructions.
89
88
  if prerequisites.should_show_rx_chakra_migration_instructions():
90
89
  prerequisites.show_rx_chakra_migration_instructions()
91
90
 
92
- # Set up the app directory, only if the config doesn't exist.
93
- if not os.path.exists(constants.Config.FILE):
94
- if template is None:
95
- template = prerequisites.prompt_for_template()
96
- prerequisites.create_config(app_name)
97
- prerequisites.initialize_app_directory(app_name, template)
98
- telemetry_event = "init"
99
- else:
100
- telemetry_event = "reinit"
101
-
102
91
  # Set up the web project.
103
92
  prerequisites.initialize_frontend_dependencies()
104
93
 
105
- # Send the telemetry event after the .web folder is initialized.
106
- telemetry.send(telemetry_event)
94
+ # Initialize the app.
95
+ prerequisites.initialize_app(app_name, template)
107
96
 
108
97
  # Migrate Pynecone projects to Reflex.
109
98
  prerequisites.migrate_to_reflex()
@@ -123,7 +112,7 @@ def init(
123
112
  name: str = typer.Option(
124
113
  None, metavar="APP_NAME", help="The name of the app to initialize."
125
114
  ),
126
- template: constants.Templates.Kind = typer.Option(
115
+ template: str = typer.Option(
127
116
  None,
128
117
  help="The template to initialize the app with.",
129
118
  ),
@@ -165,7 +154,8 @@ def _run(
165
154
  _skip_compile()
166
155
 
167
156
  # Check that the app is initialized.
168
- prerequisites.check_initialized(frontend=frontend)
157
+ if prerequisites.needs_reinit(frontend=frontend):
158
+ _init(name=config.app_name, loglevel=loglevel)
169
159
 
170
160
  # If something is running on the ports, ask the user if they want to kill or change it.
171
161
  if frontend and processes.is_process_on_port(frontend_port):
@@ -234,6 +224,11 @@ def _run(
234
224
  # In dev mode, run the backend on the main thread.
235
225
  if backend and env == constants.Env.DEV:
236
226
  backend_cmd(backend_host, int(backend_port))
227
+ # The windows uvicorn bug workaround
228
+ # https://github.com/reflex-dev/reflex/issues/2335
229
+ if constants.IS_WINDOWS and exec.frontend_process:
230
+ # Sends SIGTERM in windows
231
+ exec.kill(exec.frontend_process.pid)
237
232
 
238
233
 
239
234
  @cli.command()
@@ -289,6 +284,10 @@ def export(
289
284
  ):
290
285
  """Export the app to a zip file."""
291
286
  from reflex.utils import export as export_utils
287
+ from reflex.utils import prerequisites
288
+
289
+ if prerequisites.needs_reinit(frontend=True):
290
+ _init(name=config.app_name, loglevel=loglevel)
292
291
 
293
292
  export_utils.export(
294
293
  zipping=zipping,
@@ -524,7 +523,8 @@ def deploy(
524
523
  dependency.check_requirements()
525
524
 
526
525
  # Check if we are set up.
527
- prerequisites.check_initialized(frontend=True)
526
+ if prerequisites.needs_reinit(frontend=True):
527
+ _init(name=config.app_name, loglevel=loglevel)
528
528
  prerequisites.check_latest_package_version(constants.ReflexHostingCLI.MODULE_NAME)
529
529
 
530
530
  hosting_cli.deploy(
@@ -565,20 +565,6 @@ def demo(
565
565
  # Open the demo app in a terminal.
566
566
  webbrowser.open("https://demo.reflex.run")
567
567
 
568
- # Later: open the demo app locally.
569
- # with tempfile.TemporaryDirectory() as tmp_dir:
570
- # os.chdir(tmp_dir)
571
- # _init(
572
- # name="reflex_demo",
573
- # template=constants.Templates.Kind.DEMO,
574
- # loglevel=constants.LogLevel.DEBUG,
575
- # )
576
- # _run(
577
- # frontend_port=frontend_port,
578
- # backend_port=backend_port,
579
- # loglevel=constants.LogLevel.DEBUG,
580
- # )
581
-
582
568
 
583
569
  cli.add_typer(db_cli, name="db", help="Subcommands for managing the database schema.")
584
570
  cli.add_typer(script_cli, name="script", help="Subcommands running helper scripts.")
reflex/style.py CHANGED
@@ -22,7 +22,7 @@ color_mode_var_data = VarData( # type: ignore
22
22
  "react": {ImportVar(tag="useContext")},
23
23
  },
24
24
  hooks={
25
- f"const [ {constants.ColorMode.NAME}, {constants.ColorMode.TOGGLE} ] = useContext(ColorModeContext)",
25
+ f"const [ {constants.ColorMode.NAME}, {constants.ColorMode.TOGGLE} ] = useContext(ColorModeContext)": None,
26
26
  },
27
27
  )
28
28
  # Var resolves to the current color mode for the app ("light" or "dark")
@@ -240,9 +240,9 @@ def format_as_emotion(style_dict: dict[str, Any]) -> Style | None:
240
240
  if isinstance(value, list):
241
241
  # Apply media queries from responsive value list.
242
242
  mbps = {
243
- media_query(bp): bp_value
244
- if isinstance(bp_value, dict)
245
- else {key: bp_value}
243
+ media_query(bp): (
244
+ bp_value if isinstance(bp_value, dict) else {key: bp_value}
245
+ )
246
246
  for bp, bp_value in enumerate(value)
247
247
  }
248
248
  if key.startswith("&:"):
reflex/testing.py CHANGED
@@ -223,7 +223,7 @@ class AppHarness:
223
223
  with chdir(self.app_path):
224
224
  reflex.reflex._init(
225
225
  name=self.app_name,
226
- template=reflex.constants.Templates.Kind.BLANK,
226
+ template=reflex.constants.Templates.DEFAULT,
227
227
  loglevel=reflex.constants.LogLevel.INFO,
228
228
  )
229
229
  self.app_module_path.write_text(source_code)
reflex/utils/console.py CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import List, Optional
6
-
7
5
  from rich.console import Console
8
6
  from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
9
7
  from rich.prompt import Prompt
@@ -150,7 +148,10 @@ def error(msg: str, **kwargs):
150
148
 
151
149
 
152
150
  def ask(
153
- question: str, choices: Optional[List[str]] = None, default: Optional[str] = None
151
+ question: str,
152
+ choices: list[str] | None = None,
153
+ default: str | None = None,
154
+ show_choices: bool = True,
154
155
  ) -> str:
155
156
  """Takes a prompt question and optionally a list of choices
156
157
  and returns the user input.
@@ -159,11 +160,12 @@ def ask(
159
160
  question: The question to ask the user.
160
161
  choices: A list of choices to select from.
161
162
  default: The default option selected.
163
+ show_choices: Whether to show the choices.
162
164
 
163
165
  Returns:
164
166
  A string with the user input.
165
167
  """
166
- return Prompt.ask(question, choices=choices, default=default) # type: ignore
168
+ return Prompt.ask(question, choices=choices, default=default, show_choices=show_choices) # type: ignore
167
169
 
168
170
 
169
171
  def progress():
reflex/utils/exec.py CHANGED
@@ -7,6 +7,7 @@ import json
7
7
  import os
8
8
  import platform
9
9
  import re
10
+ import subprocess
10
11
  import sys
11
12
  from pathlib import Path
12
13
  from urllib.parse import urljoin
@@ -18,6 +19,9 @@ from reflex.config import get_config
18
19
  from reflex.utils import console, path_ops
19
20
  from reflex.utils.watch import AssetFolderWatch
20
21
 
22
+ # For uvicorn windows bug fix (#2335)
23
+ frontend_process = None
24
+
21
25
 
22
26
  def start_watching_assets_folder(root):
23
27
  """Start watching assets folder.
@@ -66,6 +70,9 @@ def kill(proc_pid: int):
66
70
  process.kill()
67
71
 
68
72
 
73
+ # run_process_and_launch_url is assumed to be used
74
+ # only to launch the frontend
75
+ # If this is not the case, might have to change the logic
69
76
  def run_process_and_launch_url(run_command: list[str]):
70
77
  """Run the process and launch the URL.
71
78
 
@@ -81,9 +88,17 @@ def run_process_and_launch_url(run_command: list[str]):
81
88
 
82
89
  while True:
83
90
  if process is None:
91
+ kwargs = {}
92
+ if constants.IS_WINDOWS:
93
+ kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore
84
94
  process = processes.new_process(
85
- run_command, cwd=constants.Dirs.WEB, shell=constants.IS_WINDOWS
95
+ run_command,
96
+ cwd=constants.Dirs.WEB,
97
+ shell=constants.IS_WINDOWS,
98
+ **kwargs,
86
99
  )
100
+ global frontend_process
101
+ frontend_process = process
87
102
  if process.stdout:
88
103
  for line in processes.stream_logs("Starting frontend", process):
89
104
  match = re.search(constants.Next.FRONTEND_LISTENING_REGEX, line)
@@ -175,6 +190,7 @@ def run_backend(
175
190
  log_level=loglevel.value,
176
191
  reload=True,
177
192
  reload_dirs=[config.app_name],
193
+ reload_excludes=[constants.Dirs.WEB],
178
194
  )
179
195
 
180
196
 
reflex/utils/export.py CHANGED
@@ -46,9 +46,6 @@ def export(
46
46
  # Show system info
47
47
  exec.output_system_info()
48
48
 
49
- # Check that the app is initialized.
50
- prerequisites.check_initialized(frontend=frontend)
51
-
52
49
  # Compile the app in production mode and export it.
53
50
  console.rule("[bold]Compiling production app and preparing for export.")
54
51