reflex 0.4.7a3__py3-none-any.whl → 0.4.8a1__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 (124) hide show
  1. reflex/.templates/web/utils/state.js +7 -1
  2. reflex/app.py +15 -1
  3. reflex/compiler/utils.py +1 -1
  4. reflex/components/base/body.pyi +0 -3
  5. reflex/components/base/document.pyi +0 -15
  6. reflex/components/base/fragment.pyi +0 -3
  7. reflex/components/base/head.pyi +0 -3
  8. reflex/components/base/link.pyi +0 -6
  9. reflex/components/base/meta.pyi +0 -12
  10. reflex/components/chakra/base.pyi +0 -6
  11. reflex/components/chakra/datadisplay/badge.pyi +0 -3
  12. reflex/components/chakra/datadisplay/code.pyi +0 -3
  13. reflex/components/chakra/datadisplay/divider.pyi +0 -3
  14. reflex/components/chakra/datadisplay/keyboard_key.pyi +0 -3
  15. reflex/components/chakra/datadisplay/list.pyi +0 -3
  16. reflex/components/chakra/datadisplay/stat.pyi +0 -15
  17. reflex/components/chakra/datadisplay/table.pyi +0 -12
  18. reflex/components/chakra/datadisplay/tag.pyi +0 -12
  19. reflex/components/chakra/disclosure/accordion.pyi +0 -12
  20. reflex/components/chakra/disclosure/tabs.pyi +0 -12
  21. reflex/components/chakra/disclosure/transition.pyi +0 -18
  22. reflex/components/chakra/disclosure/visuallyhidden.pyi +0 -3
  23. reflex/components/chakra/feedback/alert.pyi +0 -9
  24. reflex/components/chakra/feedback/circularprogress.pyi +0 -3
  25. reflex/components/chakra/feedback/progress.pyi +0 -3
  26. reflex/components/chakra/feedback/skeleton.pyi +0 -9
  27. reflex/components/chakra/feedback/spinner.pyi +0 -3
  28. reflex/components/chakra/forms/button.pyi +0 -6
  29. reflex/components/chakra/forms/checkbox.pyi +0 -6
  30. reflex/components/chakra/forms/colormodeswitch.pyi +0 -3
  31. reflex/components/chakra/forms/editable.pyi +0 -12
  32. reflex/components/chakra/forms/form.pyi +0 -9
  33. reflex/components/chakra/forms/iconbutton.pyi +0 -3
  34. reflex/components/chakra/forms/input.pyi +0 -15
  35. reflex/components/chakra/forms/numberinput.pyi +0 -12
  36. reflex/components/chakra/forms/pininput.py +1 -1
  37. reflex/components/chakra/forms/pininput.pyi +1 -4
  38. reflex/components/chakra/forms/radio.py +1 -1
  39. reflex/components/chakra/forms/radio.pyi +1 -1
  40. reflex/components/chakra/forms/rangeslider.py +1 -1
  41. reflex/components/chakra/forms/rangeslider.pyi +1 -10
  42. reflex/components/chakra/forms/slider.pyi +0 -12
  43. reflex/components/chakra/forms/switch.pyi +0 -3
  44. reflex/components/chakra/layout/aspect_ratio.pyi +0 -3
  45. reflex/components/chakra/layout/box.pyi +0 -3
  46. reflex/components/chakra/layout/card.pyi +0 -9
  47. reflex/components/chakra/layout/center.pyi +0 -9
  48. reflex/components/chakra/layout/container.pyi +0 -3
  49. reflex/components/chakra/layout/flex.pyi +0 -3
  50. reflex/components/chakra/layout/grid.pyi +0 -9
  51. reflex/components/chakra/layout/spacer.pyi +0 -3
  52. reflex/components/chakra/layout/stack.pyi +0 -9
  53. reflex/components/chakra/layout/wrap.pyi +0 -3
  54. reflex/components/chakra/media/avatar.pyi +0 -9
  55. reflex/components/chakra/media/icon.pyi +0 -3
  56. reflex/components/chakra/navigation/breadcrumb.pyi +0 -3
  57. reflex/components/chakra/navigation/linkoverlay.pyi +0 -6
  58. reflex/components/chakra/navigation/stepper.pyi +0 -24
  59. reflex/components/chakra/overlay/alertdialog.pyi +0 -18
  60. reflex/components/chakra/overlay/drawer.pyi +0 -18
  61. reflex/components/chakra/overlay/menu.pyi +0 -18
  62. reflex/components/chakra/overlay/modal.pyi +0 -18
  63. reflex/components/chakra/overlay/popover.pyi +0 -24
  64. reflex/components/chakra/overlay/tooltip.pyi +0 -3
  65. reflex/components/chakra/typography/heading.pyi +0 -3
  66. reflex/components/chakra/typography/highlight.pyi +0 -3
  67. reflex/components/chakra/typography/span.pyi +0 -3
  68. reflex/components/chakra/typography/text.pyi +0 -3
  69. reflex/components/component.py +61 -22
  70. reflex/components/core/client_side_routing.pyi +0 -6
  71. reflex/components/core/upload.py +3 -1
  72. reflex/components/core/upload.pyi +0 -3
  73. reflex/components/el/element.pyi +0 -3
  74. reflex/components/el/elements/base.pyi +0 -3
  75. reflex/components/el/elements/forms.pyi +0 -39
  76. reflex/components/el/elements/inline.pyi +0 -84
  77. reflex/components/el/elements/media.pyi +0 -42
  78. reflex/components/el/elements/metadata.pyi +0 -15
  79. reflex/components/el/elements/other.pyi +0 -21
  80. reflex/components/el/elements/scripts.pyi +0 -9
  81. reflex/components/el/elements/sectioning.pyi +0 -45
  82. reflex/components/el/elements/tables.pyi +0 -30
  83. reflex/components/el/elements/typography.pyi +0 -45
  84. reflex/components/gridjs/datatable.pyi +0 -3
  85. reflex/components/lucide/icon.pyi +0 -3
  86. reflex/components/next/base.pyi +0 -3
  87. reflex/components/next/link.pyi +0 -3
  88. reflex/components/plotly/plotly.pyi +0 -6
  89. reflex/components/radix/primitives/accordion.pyi +0 -3
  90. reflex/components/radix/primitives/base.pyi +0 -6
  91. reflex/components/radix/primitives/drawer.pyi +0 -21
  92. reflex/components/radix/primitives/form.pyi +0 -18
  93. reflex/components/radix/primitives/progress.pyi +0 -9
  94. reflex/components/radix/primitives/slider.pyi +0 -15
  95. reflex/components/radix/themes/base.pyi +0 -6
  96. reflex/components/react_player/audio.pyi +0 -3
  97. reflex/components/react_player/react_player.pyi +0 -3
  98. reflex/components/react_player/video.pyi +0 -3
  99. reflex/components/recharts/cartesian.pyi +0 -57
  100. reflex/components/recharts/general.pyi +0 -12
  101. reflex/components/recharts/polar.pyi +0 -18
  102. reflex/components/recharts/recharts.pyi +0 -3
  103. reflex/constants/__init__.py +2 -0
  104. reflex/constants/base.py +5 -0
  105. reflex/constants/compiler.py +2 -0
  106. reflex/constants/installer.py +4 -2
  107. reflex/event.py +7 -6
  108. reflex/experimental/__init__.py +2 -0
  109. reflex/experimental/misc.py +12 -0
  110. reflex/model.py +1 -1
  111. reflex/reflex.py +0 -1
  112. reflex/utils/compat.py +43 -0
  113. reflex/utils/console.py +10 -1
  114. reflex/utils/export.py +1 -3
  115. reflex/utils/imports.py +14 -1
  116. reflex/utils/prerequisites.py +65 -41
  117. reflex/utils/processes.py +37 -0
  118. reflex/utils/serializers.py +14 -0
  119. reflex/utils/types.py +1 -1
  120. {reflex-0.4.7a3.dist-info → reflex-0.4.8a1.dist-info}/METADATA +1 -2
  121. {reflex-0.4.7a3.dist-info → reflex-0.4.8a1.dist-info}/RECORD +124 -122
  122. {reflex-0.4.7a3.dist-info → reflex-0.4.8a1.dist-info}/WHEEL +1 -1
  123. {reflex-0.4.7a3.dist-info → reflex-0.4.8a1.dist-info}/LICENSE +0 -0
  124. {reflex-0.4.7a3.dist-info → reflex-0.4.8a1.dist-info}/entry_points.txt +0 -0
@@ -19,7 +19,7 @@ from datetime import datetime
19
19
  from fileinput import FileInput
20
20
  from pathlib import Path
21
21
  from types import ModuleType
22
- from typing import Callable, Optional
22
+ from typing import Callable, List, Optional
23
23
 
24
24
  import httpx
25
25
  import pkg_resources
@@ -35,6 +35,7 @@ from reflex.base import Base
35
35
  from reflex.compiler import templates
36
36
  from reflex.config import Config, get_config
37
37
  from reflex.utils import console, path_ops, processes
38
+ from reflex.utils.format import format_library_name
38
39
 
39
40
  CURRENTLY_INSTALLING_NODE = False
40
41
 
@@ -166,16 +167,13 @@ def get_bun_version() -> version.Version | None:
166
167
 
167
168
  def get_install_package_manager() -> str | None:
168
169
  """Get the package manager executable for installation.
169
- Currently on unix systems, bun is used for installation only.
170
+ Currently, bun is used for installation only.
170
171
 
171
172
  Returns:
172
173
  The path to the package manager.
173
174
  """
174
- # On Windows, we use npm instead of bun.
175
- if constants.IS_WINDOWS:
175
+ if constants.IS_WINDOWS and not constants.IS_WINDOWS_BUN_SUPPORTED_MACHINE:
176
176
  return get_package_manager()
177
-
178
- # On other platforms, we use bun.
179
177
  return get_config().bun_path
180
178
 
181
179
 
@@ -227,11 +225,12 @@ def get_app(reload: bool = False) -> ModuleType:
227
225
  return app
228
226
 
229
227
 
230
- def get_compiled_app(reload: bool = False) -> ModuleType:
228
+ def get_compiled_app(reload: bool = False, export: bool = False) -> ModuleType:
231
229
  """Get the app module based on the default config after first compiling it.
232
230
 
233
231
  Args:
234
232
  reload: Re-import the app module from disk
233
+ export: Compile the app for export
235
234
 
236
235
  Returns:
237
236
  The compiled app based on the default config.
@@ -241,7 +240,7 @@ def get_compiled_app(reload: bool = False) -> ModuleType:
241
240
  # For py3.8 and py3.9 compatibility when redis is used, we MUST add any decorator pages
242
241
  # before compiling the app in a thread to avoid event loop error (REF-2172).
243
242
  app._apply_decorated_pages()
244
- app.compile_()
243
+ app.compile_(export=export)
245
244
  return app_module
246
245
 
247
246
 
@@ -562,28 +561,37 @@ def init_reflex_json(project_hash: int | None):
562
561
  path_ops.update_json_file(constants.Reflex.JSON, reflex_json)
563
562
 
564
563
 
565
- def update_next_config(export=False):
564
+ def update_next_config(export=False, transpile_packages: Optional[List[str]] = None):
566
565
  """Update Next.js config from Reflex config.
567
566
 
568
567
  Args:
569
568
  export: if the method run during reflex export.
569
+ transpile_packages: list of packages to transpile via next.config.js.
570
570
  """
571
571
  next_config_file = os.path.join(constants.Dirs.WEB, constants.Next.CONFIG_FILE)
572
572
 
573
- next_config = _update_next_config(get_config(), export=export)
573
+ next_config = _update_next_config(
574
+ get_config(), export=export, transpile_packages=transpile_packages
575
+ )
574
576
 
575
577
  with open(next_config_file, "w") as file:
576
578
  file.write(next_config)
577
579
  file.write("\n")
578
580
 
579
581
 
580
- def _update_next_config(config, export=False):
582
+ def _update_next_config(
583
+ config: Config, export: bool = False, transpile_packages: Optional[List[str]] = None
584
+ ):
581
585
  next_config = {
582
586
  "basePath": config.frontend_path or "",
583
587
  "compress": config.next_compression,
584
588
  "reactStrictMode": True,
585
589
  "trailingSlash": True,
586
590
  }
591
+ if transpile_packages:
592
+ next_config["transpilePackages"] = list(
593
+ set((format_library_name(p) for p in transpile_packages))
594
+ )
587
595
  if export:
588
596
  next_config["output"] = "export"
589
597
  next_config["distDir"] = constants.Dirs.STATIC
@@ -718,10 +726,10 @@ def install_bun():
718
726
  Raises:
719
727
  FileNotFoundError: If required packages are not found.
720
728
  """
721
- # Bun is not supported on Windows.
722
- if constants.IS_WINDOWS:
723
- console.debug("Skipping bun installation on Windows.")
724
- return
729
+ if constants.IS_WINDOWS and not constants.IS_WINDOWS_BUN_SUPPORTED_MACHINE:
730
+ console.warn(
731
+ "Bun for Windows is currently only available for x86 64-bit Windows. Installation will fall back on npm."
732
+ )
725
733
 
726
734
  # Skip if bun is already installed.
727
735
  if os.path.exists(get_config().bun_path) and get_bun_version() == version.parse(
@@ -731,16 +739,25 @@ def install_bun():
731
739
  return
732
740
 
733
741
  # if unzip is installed
734
- unzip_path = path_ops.which("unzip")
735
- if unzip_path is None:
736
- raise FileNotFoundError("Reflex requires unzip to be installed.")
737
-
738
- # Run the bun install script.
739
- download_and_run(
740
- constants.Bun.INSTALL_URL,
741
- f"bun-v{constants.Bun.VERSION}",
742
- BUN_INSTALL=constants.Bun.ROOT_PATH,
743
- )
742
+ if constants.IS_WINDOWS:
743
+ processes.new_process(
744
+ ["powershell", "-c", f"irm {constants.Bun.INSTALL_URL}.ps1|iex"],
745
+ env={"BUN_INSTALL": constants.Bun.ROOT_PATH},
746
+ shell=True,
747
+ run=True,
748
+ show_logs=console.is_debug(),
749
+ )
750
+ else:
751
+ unzip_path = path_ops.which("unzip")
752
+ if unzip_path is None:
753
+ raise FileNotFoundError("Reflex requires unzip to be installed.")
754
+
755
+ # Run the bun install script.
756
+ download_and_run(
757
+ constants.Bun.INSTALL_URL,
758
+ f"bun-v{constants.Bun.VERSION}",
759
+ BUN_INSTALL=constants.Bun.ROOT_PATH,
760
+ )
744
761
 
745
762
 
746
763
  def _write_cached_procedure_file(payload: str, cache_file: str):
@@ -802,18 +819,22 @@ def install_frontend_packages(packages: set[str], config: Config):
802
819
  Example:
803
820
  >>> install_frontend_packages(["react", "react-dom"], get_config())
804
821
  """
805
- # Install the base packages.
806
- process = processes.new_process(
822
+ # unsupported archs will use npm anyway. so we dont have to run npm twice
823
+ fallback_command = (
824
+ get_package_manager()
825
+ if constants.IS_WINDOWS and constants.IS_WINDOWS_BUN_SUPPORTED_MACHINE
826
+ else None
827
+ )
828
+ processes.run_process_with_fallback(
807
829
  [get_install_package_manager(), "install", "--loglevel", "silly"],
830
+ fallback=fallback_command,
831
+ show_status_message="Installing base frontend packages",
808
832
  cwd=constants.Dirs.WEB,
809
833
  shell=constants.IS_WINDOWS,
810
834
  )
811
835
 
812
- processes.show_status("Installing base frontend packages", process)
813
-
814
836
  if config.tailwind is not None:
815
- # install tailwind and tailwind plugins as dev dependencies.
816
- process = processes.new_process(
837
+ processes.run_process_with_fallback(
817
838
  [
818
839
  get_install_package_manager(),
819
840
  "add",
@@ -821,21 +842,21 @@ def install_frontend_packages(packages: set[str], config: Config):
821
842
  constants.Tailwind.VERSION,
822
843
  *((config.tailwind or {}).get("plugins", [])),
823
844
  ],
845
+ fallback=fallback_command,
846
+ show_status_message="Installing tailwind",
824
847
  cwd=constants.Dirs.WEB,
825
848
  shell=constants.IS_WINDOWS,
826
849
  )
827
- processes.show_status("Installing tailwind", process)
828
850
 
829
851
  # Install custom packages defined in frontend_packages
830
852
  if len(packages) > 0:
831
- process = processes.new_process(
853
+ processes.run_process_with_fallback(
832
854
  [get_install_package_manager(), "add", *packages],
855
+ fallback=fallback_command,
856
+ show_status_message="Installing frontend packages from config and components",
833
857
  cwd=constants.Dirs.WEB,
834
858
  shell=constants.IS_WINDOWS,
835
859
  )
836
- processes.show_status(
837
- "Installing frontend packages from config and components", process
838
- )
839
860
 
840
861
 
841
862
  def needs_reinit(frontend: bool = True) -> bool:
@@ -856,12 +877,16 @@ def needs_reinit(frontend: bool = True) -> bool:
856
877
  )
857
878
  raise typer.Exit(1)
858
879
 
880
+ # Don't need to reinit if not running in frontend mode.
881
+ if not frontend:
882
+ return False
883
+
859
884
  # Make sure the .reflex directory exists.
860
885
  if not os.path.exists(constants.Reflex.DIR):
861
886
  return True
862
887
 
863
888
  # Make sure the .web directory exists in frontend mode.
864
- if frontend and not os.path.exists(constants.Dirs.WEB):
889
+ if not os.path.exists(constants.Dirs.WEB):
865
890
  return True
866
891
 
867
892
  if constants.IS_WINDOWS:
@@ -938,9 +963,6 @@ def validate_frontend_dependencies(init=True):
938
963
  )
939
964
  raise typer.Exit(1)
940
965
 
941
- if constants.IS_WINDOWS:
942
- return
943
-
944
966
  if init:
945
967
  # we only need bun for package install on `reflex init`.
946
968
  validate_bun()
@@ -1369,7 +1391,9 @@ def initialize_app(app_name: str, template: str | None = None):
1369
1391
  else:
1370
1392
  # Check if the template is a github repo.
1371
1393
  if template.startswith("https://github.com"):
1372
- template_url = f"{template.strip('/')}/archive/main.zip"
1394
+ template_url = (
1395
+ f"{template.strip('/').replace('.git', '')}/archive/main.zip"
1396
+ )
1373
1397
  else:
1374
1398
  console.error(f"Template `{template}` not found.")
1375
1399
  raise typer.Exit(1)
reflex/utils/processes.py CHANGED
@@ -287,3 +287,40 @@ def show_progress(message: str, process: subprocess.Popen, checkpoints: List[str
287
287
  def atexit_handler():
288
288
  """Display a custom message with the current time when exiting an app."""
289
289
  console.log("Reflex app stopped.")
290
+
291
+
292
+ def run_process_with_fallback(args, *, show_status_message, fallback=None, **kwargs):
293
+ """Run subprocess and retry using fallback command if initial command fails.
294
+
295
+ Args:
296
+ args: A string, or a sequence of program arguments.
297
+ show_status_message: The status message to be displayed in the console.
298
+ fallback: The fallback command to run.
299
+ kwargs: Kwargs to pass to new_process function.
300
+ """
301
+
302
+ def execute_process(process):
303
+ if not constants.IS_WINDOWS:
304
+ show_status(show_status_message, process)
305
+ else:
306
+ process.wait()
307
+ if process.returncode != 0:
308
+ error_output = process.stderr if process.stderr else process.stdout
309
+ error_message = f"Error occurred during subprocess execution: {' '.join(args)}\n{error_output.read() if error_output else ''}"
310
+ # Only show error in debug mode.
311
+ if console.is_debug():
312
+ console.error(error_message)
313
+
314
+ # retry with fallback command.
315
+ fallback_args = [fallback, *args[1:]] if fallback else None
316
+ console.warn(
317
+ f"There was an error running command: {args}. Falling back to: {fallback_args}."
318
+ )
319
+ if fallback_args:
320
+ process = new_process(fallback_args, **kwargs)
321
+ execute_process(process)
322
+ else:
323
+ show_status(show_status_message, process)
324
+
325
+ process = new_process(args, **kwargs)
326
+ execute_process(process)
@@ -6,6 +6,7 @@ import json
6
6
  import types as builtin_types
7
7
  import warnings
8
8
  from datetime import date, datetime, time, timedelta
9
+ from enum import Enum
9
10
  from typing import Any, Callable, Dict, List, Set, Tuple, Type, Union, get_type_hints
10
11
 
11
12
  from reflex.base import Base
@@ -232,6 +233,19 @@ def serialize_datetime(dt: Union[date, datetime, time, timedelta]) -> str:
232
233
  return str(dt)
233
234
 
234
235
 
236
+ @serializer
237
+ def serialize_enum(en: Enum) -> str:
238
+ """Serialize a enum to a JSON string.
239
+
240
+ Args:
241
+ en: The enum to serialize.
242
+
243
+ Returns:
244
+ The serialized enum.
245
+ """
246
+ return en.value
247
+
248
+
235
249
  @serializer
236
250
  def serialize_color(color: Color) -> str:
237
251
  """Serialize a color.
reflex/utils/types.py CHANGED
@@ -29,7 +29,7 @@ try:
29
29
  # reflex-hosting-cli tools are compatible with pydantic v2
30
30
 
31
31
  if not TYPE_CHECKING:
32
- import pydantic.v1.fields as ModelField
32
+ from pydantic.v1.fields import ModelField
33
33
  else:
34
34
  raise ModuleNotFoundError
35
35
  except ModuleNotFoundError:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: reflex
3
- Version: 0.4.7a3
3
+ Version: 0.4.8a1
4
4
  Summary: Web apps in pure Python.
5
5
  Home-page: https://reflex.dev
6
6
  License: Apache-2.0
@@ -15,7 +15,6 @@ Classifier: Programming Language :: Python :: 3.8
15
15
  Classifier: Programming Language :: Python :: 3.9
16
16
  Classifier: Programming Language :: Python :: 3.10
17
17
  Classifier: Programming Language :: Python :: 3.11
18
- Classifier: Programming Language :: Python :: 3.12
19
18
  Requires-Dist: alembic (>=1.11.1,<2.0)
20
19
  Requires-Dist: build (>=1.0.3,<2.0)
21
20
  Requires-Dist: charset-normalizer (>=3.3.2,<4.0)