reflex 0.2.2__py3-none-any.whl → 0.2.3__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.
- reflex/.templates/apps/counter/counter.py +1 -1
- reflex/.templates/apps/default/default.py +1 -1
- reflex/.templates/web/utils/state.js +5 -1
- reflex/__init__.py +1 -0
- reflex/app.py +40 -24
- reflex/components/datadisplay/datatable.py +16 -19
- reflex/components/navigation/breadcrumb.py +31 -8
- reflex/components/tags/iter_tag.py +1 -1
- reflex/components/tags/tag.py +40 -38
- reflex/components/typography/heading.py +3 -0
- reflex/components/typography/markdown.py +86 -30
- reflex/config.py +0 -6
- reflex/constants.py +59 -14
- reflex/model.py +2 -2
- reflex/page.py +66 -0
- reflex/reflex.py +93 -79
- reflex/route.py +11 -21
- reflex/state.py +29 -12
- reflex/testing.py +3 -1
- reflex/utils/build.py +17 -61
- reflex/utils/console.py +112 -22
- reflex/utils/exec.py +25 -42
- reflex/utils/format.py +19 -0
- reflex/utils/imports.py +1 -1
- reflex/utils/prerequisites.py +242 -145
- reflex/utils/processes.py +96 -16
- {reflex-0.2.2.dist-info → reflex-0.2.3.dist-info}/METADATA +2 -2
- {reflex-0.2.2.dist-info → reflex-0.2.3.dist-info}/RECORD +31 -30
- {reflex-0.2.2.dist-info → reflex-0.2.3.dist-info}/WHEEL +1 -1
- reflex-0.2.3.dist-info/entry_points.txt +3 -0
- reflex-0.2.2.dist-info/entry_points.txt +0 -3
- {reflex-0.2.2.dist-info → reflex-0.2.3.dist-info}/LICENSE +0 -0
reflex/utils/build.py
CHANGED
|
@@ -9,12 +9,9 @@ import subprocess
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from typing import Optional, Union
|
|
11
11
|
|
|
12
|
-
from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
|
|
13
|
-
|
|
14
12
|
from reflex import constants
|
|
15
13
|
from reflex.config import get_config
|
|
16
|
-
from reflex.utils import console, path_ops, prerequisites
|
|
17
|
-
from reflex.utils.processes import new_process
|
|
14
|
+
from reflex.utils import console, path_ops, prerequisites, processes
|
|
18
15
|
|
|
19
16
|
|
|
20
17
|
def update_json_file(file_path: str, update_dict: dict[str, Union[int, str]]):
|
|
@@ -39,7 +36,9 @@ def update_json_file(file_path: str, update_dict: dict[str, Union[int, str]]):
|
|
|
39
36
|
|
|
40
37
|
def set_reflex_project_hash():
|
|
41
38
|
"""Write the hash of the Reflex project to a REFLEX_JSON."""
|
|
42
|
-
|
|
39
|
+
project_hash = random.getrandbits(128)
|
|
40
|
+
console.debug(f"Setting project hash to {project_hash}.")
|
|
41
|
+
update_json_file(constants.REFLEX_JSON, {"project_hash": project_hash})
|
|
43
42
|
|
|
44
43
|
|
|
45
44
|
def set_environment_variables():
|
|
@@ -86,21 +85,19 @@ def generate_sitemap_config(deploy_url: str):
|
|
|
86
85
|
f.write(templates.SITEMAP_CONFIG(config=config))
|
|
87
86
|
|
|
88
87
|
|
|
89
|
-
def
|
|
88
|
+
def export(
|
|
90
89
|
backend: bool = True,
|
|
91
90
|
frontend: bool = True,
|
|
92
91
|
zip: bool = False,
|
|
93
92
|
deploy_url: Optional[str] = None,
|
|
94
|
-
loglevel: constants.LogLevel = constants.LogLevel.ERROR,
|
|
95
93
|
):
|
|
96
|
-
"""
|
|
94
|
+
"""Export the app for deployment.
|
|
97
95
|
|
|
98
96
|
Args:
|
|
99
97
|
backend: Whether to zip up the backend app.
|
|
100
98
|
frontend: Whether to zip up the frontend app.
|
|
101
99
|
zip: Whether to zip the app.
|
|
102
100
|
deploy_url: The URL of the deployed app.
|
|
103
|
-
loglevel: The log level to use.
|
|
104
101
|
"""
|
|
105
102
|
# Remove the static folder.
|
|
106
103
|
path_ops.rm(constants.WEB_STATIC_DIR)
|
|
@@ -111,13 +108,6 @@ def export_app(
|
|
|
111
108
|
generate_sitemap_config(deploy_url)
|
|
112
109
|
command = "export-sitemap"
|
|
113
110
|
|
|
114
|
-
# Create a progress object
|
|
115
|
-
progress = Progress(
|
|
116
|
-
*Progress.get_default_columns()[:-1],
|
|
117
|
-
MofNCompleteColumn(),
|
|
118
|
-
TimeElapsedColumn(),
|
|
119
|
-
)
|
|
120
|
-
|
|
121
111
|
checkpoints = [
|
|
122
112
|
"Linting and checking ",
|
|
123
113
|
"Compiled successfully",
|
|
@@ -130,36 +120,12 @@ def export_app(
|
|
|
130
120
|
"Export successful",
|
|
131
121
|
]
|
|
132
122
|
|
|
133
|
-
# Add a single task to the progress object
|
|
134
|
-
task = progress.add_task("Creating Production Build: ", total=len(checkpoints))
|
|
135
|
-
|
|
136
123
|
# Start the subprocess with the progress bar.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
assert export_process.stdout is not None, "No stdout for export process."
|
|
143
|
-
for line in export_process.stdout:
|
|
144
|
-
if loglevel == constants.LogLevel.DEBUG:
|
|
145
|
-
print(line, end="")
|
|
146
|
-
|
|
147
|
-
# Check for special strings and update the progress bar.
|
|
148
|
-
for special_string in checkpoints:
|
|
149
|
-
if special_string in line:
|
|
150
|
-
if special_string == "Export successful":
|
|
151
|
-
progress.update(task, completed=len(checkpoints))
|
|
152
|
-
break # Exit the loop if the completion message is found
|
|
153
|
-
else:
|
|
154
|
-
progress.update(task, advance=1)
|
|
155
|
-
break
|
|
156
|
-
|
|
157
|
-
except Exception as e:
|
|
158
|
-
console.print(f"[red]Export process errored: {e}")
|
|
159
|
-
console.print(
|
|
160
|
-
"[red]Run in with [bold]--loglevel debug[/bold] to see the full error."
|
|
161
|
-
)
|
|
162
|
-
os._exit(1)
|
|
124
|
+
process = processes.new_process(
|
|
125
|
+
[prerequisites.get_package_manager(), "run", command],
|
|
126
|
+
cwd=constants.WEB_DIR,
|
|
127
|
+
)
|
|
128
|
+
processes.show_progress("Creating Production Build", process, checkpoints)
|
|
163
129
|
|
|
164
130
|
# Zip up the app.
|
|
165
131
|
if zip:
|
|
@@ -203,24 +169,16 @@ def posix_export(backend: bool = True, frontend: bool = True):
|
|
|
203
169
|
|
|
204
170
|
def setup_frontend(
|
|
205
171
|
root: Path,
|
|
206
|
-
loglevel: constants.LogLevel = constants.LogLevel.ERROR,
|
|
207
172
|
disable_telemetry: bool = True,
|
|
208
173
|
):
|
|
209
|
-
"""Set up the frontend.
|
|
174
|
+
"""Set up the frontend to run the app.
|
|
210
175
|
|
|
211
176
|
Args:
|
|
212
177
|
root: The root path of the project.
|
|
213
|
-
loglevel: The log level to use.
|
|
214
178
|
disable_telemetry: Whether to disable the Next telemetry.
|
|
215
179
|
"""
|
|
216
|
-
# Validate bun version.
|
|
217
|
-
prerequisites.validate_and_install_bun(initialize=False)
|
|
218
|
-
|
|
219
|
-
# Initialize the web directory if it doesn't exist.
|
|
220
|
-
web_dir = prerequisites.create_web_directory(root)
|
|
221
|
-
|
|
222
180
|
# Install frontend packages.
|
|
223
|
-
prerequisites.install_frontend_packages(
|
|
181
|
+
prerequisites.install_frontend_packages()
|
|
224
182
|
|
|
225
183
|
# Copy asset files to public folder.
|
|
226
184
|
path_ops.cp(
|
|
@@ -228,12 +186,12 @@ def setup_frontend(
|
|
|
228
186
|
dest=str(root / constants.WEB_ASSETS_DIR),
|
|
229
187
|
)
|
|
230
188
|
|
|
231
|
-
#
|
|
189
|
+
# Set the environment variables in client (env.json).
|
|
232
190
|
set_environment_variables()
|
|
233
191
|
|
|
234
192
|
# Disable the Next telemetry.
|
|
235
193
|
if disable_telemetry:
|
|
236
|
-
new_process(
|
|
194
|
+
processes.new_process(
|
|
237
195
|
[
|
|
238
196
|
prerequisites.get_package_manager(),
|
|
239
197
|
"run",
|
|
@@ -248,15 +206,13 @@ def setup_frontend(
|
|
|
248
206
|
|
|
249
207
|
def setup_frontend_prod(
|
|
250
208
|
root: Path,
|
|
251
|
-
loglevel: constants.LogLevel = constants.LogLevel.ERROR,
|
|
252
209
|
disable_telemetry: bool = True,
|
|
253
210
|
):
|
|
254
211
|
"""Set up the frontend for prod mode.
|
|
255
212
|
|
|
256
213
|
Args:
|
|
257
214
|
root: The root path of the project.
|
|
258
|
-
loglevel: The log level to use.
|
|
259
215
|
disable_telemetry: Whether to disable the Next telemetry.
|
|
260
216
|
"""
|
|
261
|
-
setup_frontend(root,
|
|
262
|
-
|
|
217
|
+
setup_frontend(root, disable_telemetry)
|
|
218
|
+
export(deploy_url=get_config().deploy_url)
|
reflex/utils/console.py
CHANGED
|
@@ -5,47 +5,123 @@ from __future__ import annotations
|
|
|
5
5
|
from typing import List, Optional
|
|
6
6
|
|
|
7
7
|
from rich.console import Console
|
|
8
|
+
from rich.progress import MofNCompleteColumn, Progress, TimeElapsedColumn
|
|
8
9
|
from rich.prompt import Prompt
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
from reflex.constants import LogLevel
|
|
10
12
|
|
|
11
13
|
# Console for pretty printing.
|
|
12
14
|
_console = Console()
|
|
13
15
|
|
|
16
|
+
# The current log level.
|
|
17
|
+
LOG_LEVEL = LogLevel.INFO
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
|
|
20
|
+
def set_log_level(log_level: LogLevel):
|
|
21
|
+
"""Set the log level.
|
|
17
22
|
|
|
18
23
|
Args:
|
|
19
|
-
|
|
24
|
+
log_level: The log level to set.
|
|
20
25
|
"""
|
|
21
|
-
|
|
26
|
+
global LOG_LEVEL
|
|
27
|
+
LOG_LEVEL = log_level
|
|
22
28
|
|
|
23
29
|
|
|
24
|
-
def
|
|
25
|
-
"""
|
|
30
|
+
def print(msg: str, **kwargs):
|
|
31
|
+
"""Print a message.
|
|
26
32
|
|
|
27
33
|
Args:
|
|
28
|
-
msg: The message to
|
|
34
|
+
msg: The message to print.
|
|
35
|
+
kwargs: Keyword arguments to pass to the print function.
|
|
29
36
|
"""
|
|
30
|
-
_console.
|
|
37
|
+
_console.print(msg, **kwargs)
|
|
31
38
|
|
|
32
39
|
|
|
33
|
-
def
|
|
34
|
-
"""
|
|
40
|
+
def debug(msg: str, **kwargs):
|
|
41
|
+
"""Print a debug message.
|
|
35
42
|
|
|
36
43
|
Args:
|
|
37
|
-
msg: The message
|
|
44
|
+
msg: The debug message.
|
|
45
|
+
kwargs: Keyword arguments to pass to the print function.
|
|
46
|
+
"""
|
|
47
|
+
if LOG_LEVEL <= LogLevel.DEBUG:
|
|
48
|
+
print(f"[blue]Debug: {msg}[/blue]", **kwargs)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def info(msg: str, **kwargs):
|
|
52
|
+
"""Print an info message.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
msg: The info message.
|
|
56
|
+
kwargs: Keyword arguments to pass to the print function.
|
|
57
|
+
"""
|
|
58
|
+
if LOG_LEVEL <= LogLevel.INFO:
|
|
59
|
+
print(f"[cyan]Info: {msg}[/cyan]", **kwargs)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def success(msg: str, **kwargs):
|
|
63
|
+
"""Print a success message.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
msg: The success message.
|
|
67
|
+
kwargs: Keyword arguments to pass to the print function.
|
|
68
|
+
"""
|
|
69
|
+
if LOG_LEVEL <= LogLevel.INFO:
|
|
70
|
+
print(f"[green]Success: {msg}[/green]", **kwargs)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def log(msg: str, **kwargs):
|
|
74
|
+
"""Takes a string and logs it to the console.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
msg: The message to log.
|
|
78
|
+
kwargs: Keyword arguments to pass to the print function.
|
|
38
79
|
"""
|
|
39
|
-
|
|
80
|
+
if LOG_LEVEL <= LogLevel.INFO:
|
|
81
|
+
_console.log(msg, **kwargs)
|
|
40
82
|
|
|
41
83
|
|
|
42
|
-
def rule(title: str)
|
|
84
|
+
def rule(title: str, **kwargs):
|
|
43
85
|
"""Prints a horizontal rule with a title.
|
|
44
86
|
|
|
45
87
|
Args:
|
|
46
88
|
title: The title of the rule.
|
|
89
|
+
kwargs: Keyword arguments to pass to the print function.
|
|
47
90
|
"""
|
|
48
|
-
_console.rule(title)
|
|
91
|
+
_console.rule(title, **kwargs)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def warn(msg: str, **kwargs):
|
|
95
|
+
"""Print a warning message.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
msg: The warning message.
|
|
99
|
+
kwargs: Keyword arguments to pass to the print function.
|
|
100
|
+
"""
|
|
101
|
+
if LOG_LEVEL <= LogLevel.WARNING:
|
|
102
|
+
print(f"[orange1]Warning: {msg}[/orange1]", **kwargs)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def deprecate(msg: str, **kwargs):
|
|
106
|
+
"""Print a deprecation warning.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
msg: The deprecation message.
|
|
110
|
+
kwargs: Keyword arguments to pass to the print function.
|
|
111
|
+
"""
|
|
112
|
+
if LOG_LEVEL <= LogLevel.WARNING:
|
|
113
|
+
print(f"[yellow]DeprecationWarning: {msg}[/yellow]", **kwargs)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def error(msg: str, **kwargs):
|
|
117
|
+
"""Print an error message.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
msg: The error message.
|
|
121
|
+
kwargs: Keyword arguments to pass to the print function.
|
|
122
|
+
"""
|
|
123
|
+
if LOG_LEVEL <= LogLevel.ERROR:
|
|
124
|
+
print(f"[red]Error: {msg}[/red]", **kwargs)
|
|
49
125
|
|
|
50
126
|
|
|
51
127
|
def ask(
|
|
@@ -60,19 +136,33 @@ def ask(
|
|
|
60
136
|
default: The default option selected.
|
|
61
137
|
|
|
62
138
|
Returns:
|
|
63
|
-
A string
|
|
139
|
+
A string with the user input.
|
|
64
140
|
"""
|
|
65
141
|
return Prompt.ask(question, choices=choices, default=default) # type: ignore
|
|
66
142
|
|
|
67
143
|
|
|
68
|
-
def
|
|
69
|
-
"""
|
|
70
|
-
|
|
144
|
+
def progress():
|
|
145
|
+
"""Create a new progress bar.
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
A new progress bar.
|
|
150
|
+
"""
|
|
151
|
+
return Progress(
|
|
152
|
+
*Progress.get_default_columns()[:-1],
|
|
153
|
+
MofNCompleteColumn(),
|
|
154
|
+
TimeElapsedColumn(),
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def status(*args, **kwargs):
|
|
159
|
+
"""Create a status with a spinner.
|
|
71
160
|
|
|
72
161
|
Args:
|
|
73
|
-
|
|
162
|
+
*args: Args to pass to the status.
|
|
163
|
+
**kwargs: Kwargs to pass to the status.
|
|
74
164
|
|
|
75
165
|
Returns:
|
|
76
|
-
|
|
166
|
+
A new status.
|
|
77
167
|
"""
|
|
78
|
-
return _console.status(
|
|
168
|
+
return _console.status(*args, **kwargs)
|
reflex/utils/exec.py
CHANGED
|
@@ -3,16 +3,11 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import os
|
|
6
|
-
import platform
|
|
7
|
-
import subprocess
|
|
8
6
|
from pathlib import Path
|
|
9
7
|
|
|
10
|
-
from rich import print
|
|
11
|
-
|
|
12
8
|
from reflex import constants
|
|
13
9
|
from reflex.config import get_config
|
|
14
10
|
from reflex.utils import console, prerequisites, processes
|
|
15
|
-
from reflex.utils.processes import new_process
|
|
16
11
|
from reflex.utils.watch import AssetFolderWatch
|
|
17
12
|
|
|
18
13
|
|
|
@@ -28,15 +23,13 @@ def start_watching_assets_folder(root):
|
|
|
28
23
|
|
|
29
24
|
def run_process_and_launch_url(
|
|
30
25
|
run_command: list[str],
|
|
31
|
-
loglevel: constants.LogLevel = constants.LogLevel.ERROR,
|
|
32
26
|
):
|
|
33
27
|
"""Run the process and launch the URL.
|
|
34
28
|
|
|
35
29
|
Args:
|
|
36
30
|
run_command: The command to run.
|
|
37
|
-
loglevel: The log level to use.
|
|
38
31
|
"""
|
|
39
|
-
process = new_process(
|
|
32
|
+
process = processes.new_process(
|
|
40
33
|
run_command,
|
|
41
34
|
cwd=constants.WEB_DIR,
|
|
42
35
|
)
|
|
@@ -45,22 +38,20 @@ def run_process_and_launch_url(
|
|
|
45
38
|
for line in process.stdout:
|
|
46
39
|
if "ready started server on" in line:
|
|
47
40
|
url = line.split("url: ")[-1].strip()
|
|
48
|
-
print(f"App running at: [bold green]{url}")
|
|
49
|
-
|
|
50
|
-
|
|
41
|
+
console.print(f"App running at: [bold green]{url}")
|
|
42
|
+
else:
|
|
43
|
+
console.debug(line)
|
|
51
44
|
|
|
52
45
|
|
|
53
46
|
def run_frontend(
|
|
54
47
|
root: Path,
|
|
55
48
|
port: str,
|
|
56
|
-
loglevel: constants.LogLevel = constants.LogLevel.ERROR,
|
|
57
49
|
):
|
|
58
50
|
"""Run the frontend.
|
|
59
51
|
|
|
60
52
|
Args:
|
|
61
53
|
root: The root path of the project.
|
|
62
54
|
port: The port to run the frontend on.
|
|
63
|
-
loglevel: The log level to use.
|
|
64
55
|
"""
|
|
65
56
|
# Start watching asset folder.
|
|
66
57
|
start_watching_assets_folder(root)
|
|
@@ -68,31 +59,25 @@ def run_frontend(
|
|
|
68
59
|
# Run the frontend in development mode.
|
|
69
60
|
console.rule("[bold green]App Running")
|
|
70
61
|
os.environ["PORT"] = get_config().frontend_port if port is None else port
|
|
71
|
-
run_process_and_launch_url(
|
|
72
|
-
[prerequisites.get_package_manager(), "run", "dev"], loglevel
|
|
73
|
-
)
|
|
62
|
+
run_process_and_launch_url([prerequisites.get_package_manager(), "run", "dev"])
|
|
74
63
|
|
|
75
64
|
|
|
76
65
|
def run_frontend_prod(
|
|
77
66
|
root: Path,
|
|
78
67
|
port: str,
|
|
79
|
-
loglevel: constants.LogLevel = constants.LogLevel.ERROR,
|
|
80
68
|
):
|
|
81
69
|
"""Run the frontend.
|
|
82
70
|
|
|
83
71
|
Args:
|
|
84
72
|
root: The root path of the project (to keep same API as run_frontend).
|
|
85
73
|
port: The port to run the frontend on.
|
|
86
|
-
loglevel: The log level to use.
|
|
87
74
|
"""
|
|
88
75
|
# Set the port.
|
|
89
76
|
os.environ["PORT"] = get_config().frontend_port if port is None else port
|
|
90
77
|
|
|
91
78
|
# Run the frontend in production mode.
|
|
92
79
|
console.rule("[bold green]App Running")
|
|
93
|
-
run_process_and_launch_url(
|
|
94
|
-
[prerequisites.get_package_manager(), "run", "prod"], loglevel
|
|
95
|
-
)
|
|
80
|
+
run_process_and_launch_url([constants.NPM_PATH, "run", "prod"])
|
|
96
81
|
|
|
97
82
|
|
|
98
83
|
def run_backend(
|
|
@@ -109,25 +94,23 @@ def run_backend(
|
|
|
109
94
|
port: The app port
|
|
110
95
|
loglevel: The log level.
|
|
111
96
|
"""
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
except KeyboardInterrupt:
|
|
130
|
-
process.terminate()
|
|
97
|
+
processes.new_process(
|
|
98
|
+
[
|
|
99
|
+
"uvicorn",
|
|
100
|
+
f"{app_name}:{constants.APP_VAR}.{constants.API_VAR}",
|
|
101
|
+
"--host",
|
|
102
|
+
host,
|
|
103
|
+
"--port",
|
|
104
|
+
str(port),
|
|
105
|
+
"--log-level",
|
|
106
|
+
loglevel,
|
|
107
|
+
"--reload",
|
|
108
|
+
"--reload-dir",
|
|
109
|
+
app_name.split(".")[0],
|
|
110
|
+
],
|
|
111
|
+
run=True,
|
|
112
|
+
show_logs=True,
|
|
113
|
+
)
|
|
131
114
|
|
|
132
115
|
|
|
133
116
|
def run_backend_prod(
|
|
@@ -154,7 +137,7 @@ def run_backend_prod(
|
|
|
154
137
|
str(port),
|
|
155
138
|
f"{app_name}:{constants.APP_VAR}",
|
|
156
139
|
]
|
|
157
|
-
if
|
|
140
|
+
if prerequisites.IS_WINDOWS
|
|
158
141
|
else [
|
|
159
142
|
*constants.RUN_BACKEND_PROD,
|
|
160
143
|
"--bind",
|
|
@@ -171,4 +154,4 @@ def run_backend_prod(
|
|
|
171
154
|
"--workers",
|
|
172
155
|
str(num_workers),
|
|
173
156
|
]
|
|
174
|
-
|
|
157
|
+
processes.new_process(command, run=True, show_logs=True)
|
reflex/utils/format.py
CHANGED
|
@@ -6,6 +6,7 @@ import base64
|
|
|
6
6
|
import io
|
|
7
7
|
import json
|
|
8
8
|
import os
|
|
9
|
+
import os.path as op
|
|
9
10
|
import re
|
|
10
11
|
import sys
|
|
11
12
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type
|
|
@@ -460,6 +461,24 @@ def format_dict(prop: ComponentStyle) -> str:
|
|
|
460
461
|
return fprop
|
|
461
462
|
|
|
462
463
|
|
|
464
|
+
def format_breadcrumbs(route: str) -> list[tuple[str, str]]:
|
|
465
|
+
"""Take a route and return a list of tuple for use in breadcrumb.
|
|
466
|
+
|
|
467
|
+
Args:
|
|
468
|
+
route: The route to transform.
|
|
469
|
+
|
|
470
|
+
Returns:
|
|
471
|
+
list[tuple[str, str]]: the list of tuples for the breadcrumb.
|
|
472
|
+
"""
|
|
473
|
+
route_parts = route.lstrip("/").split("/")
|
|
474
|
+
|
|
475
|
+
# create and return breadcrumbs
|
|
476
|
+
return [
|
|
477
|
+
(part, op.join("/", *route_parts[: i + 1]))
|
|
478
|
+
for i, part in enumerate(route_parts)
|
|
479
|
+
]
|
|
480
|
+
|
|
481
|
+
|
|
463
482
|
def json_dumps(obj: Any) -> str:
|
|
464
483
|
"""Takes an object and returns a jsonified string.
|
|
465
484
|
|
reflex/utils/imports.py
CHANGED