reflex 0.7.8a1__py3-none-any.whl → 0.7.9a2__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/jinja/web/tailwind.config.js.jinja2 +65 -31
- reflex/.templates/web/utils/state.js +11 -1
- reflex/app.py +191 -87
- reflex/app_mixins/lifespan.py +2 -2
- reflex/compiler/compiler.py +31 -4
- reflex/components/base/body.pyi +3 -197
- reflex/components/base/link.pyi +4 -392
- reflex/components/base/meta.pyi +28 -608
- reflex/components/component.py +39 -57
- reflex/components/core/upload.py +8 -0
- reflex/components/dynamic.py +9 -1
- reflex/components/el/elements/metadata.pyi +0 -1
- reflex/components/markdown/markdown.py +0 -21
- reflex/components/markdown/markdown.pyi +2 -2
- reflex/components/radix/primitives/accordion.py +1 -1
- reflex/components/radix/primitives/form.py +1 -1
- reflex/components/radix/primitives/progress.py +1 -1
- reflex/components/radix/primitives/slider.py +1 -1
- reflex/components/radix/themes/color_mode.py +1 -1
- reflex/components/radix/themes/color_mode.pyi +1 -1
- reflex/components/radix/themes/layout/list.pyi +2 -391
- reflex/components/recharts/recharts.py +2 -2
- reflex/components/sonner/toast.py +1 -1
- reflex/config.py +4 -7
- reflex/constants/base.py +21 -0
- reflex/constants/installer.py +6 -6
- reflex/custom_components/custom_components.py +67 -64
- reflex/event.py +2 -0
- reflex/page.py +8 -0
- reflex/reflex.py +277 -265
- reflex/testing.py +30 -24
- reflex/utils/codespaces.py +6 -2
- reflex/utils/console.py +4 -3
- reflex/utils/exec.py +60 -24
- reflex/utils/format.py +17 -2
- reflex/utils/prerequisites.py +43 -30
- reflex/utils/processes.py +6 -6
- reflex/utils/types.py +11 -6
- reflex/vars/base.py +19 -1
- {reflex-0.7.8a1.dist-info → reflex-0.7.9a2.dist-info}/METADATA +6 -9
- {reflex-0.7.8a1.dist-info → reflex-0.7.9a2.dist-info}/RECORD +44 -44
- {reflex-0.7.8a1.dist-info → reflex-0.7.9a2.dist-info}/WHEEL +0 -0
- {reflex-0.7.8a1.dist-info → reflex-0.7.9a2.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.8a1.dist-info → reflex-0.7.9a2.dist-info}/licenses/LICENSE +0 -0
reflex/reflex.py
CHANGED
|
@@ -3,74 +3,63 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import atexit
|
|
6
|
+
from importlib.util import find_spec
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from typing import TYPE_CHECKING
|
|
8
9
|
|
|
9
|
-
import
|
|
10
|
-
import typer.core
|
|
10
|
+
import click
|
|
11
11
|
from reflex_cli.v2.deployments import hosting_cli
|
|
12
12
|
|
|
13
13
|
from reflex import constants
|
|
14
14
|
from reflex.config import environment, get_config
|
|
15
|
+
from reflex.constants.base import LITERAL_ENV
|
|
15
16
|
from reflex.custom_components.custom_components import custom_components_cli
|
|
16
17
|
from reflex.state import reset_disk_state_manager
|
|
17
18
|
from reflex.utils import console, redir, telemetry
|
|
18
19
|
from reflex.utils.exec import should_use_granian
|
|
19
20
|
|
|
20
|
-
# Disable typer+rich integration for help panels
|
|
21
|
-
typer.core.rich = None # pyright: ignore [reportPrivateImportUsage]
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def version(value: bool):
|
|
28
|
-
"""Get the Reflex version.
|
|
22
|
+
def set_loglevel(ctx: click.Context, self: click.Parameter, value: str | None):
|
|
23
|
+
"""Set the log level.
|
|
29
24
|
|
|
30
25
|
Args:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
typer.Exit: If the version flag was passed.
|
|
26
|
+
ctx: The click context.
|
|
27
|
+
self: The click command.
|
|
28
|
+
value: The log level to set.
|
|
35
29
|
"""
|
|
36
|
-
if value:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
None,
|
|
45
|
-
"-v",
|
|
46
|
-
"--version",
|
|
47
|
-
callback=version,
|
|
48
|
-
help="Get the Reflex version.",
|
|
49
|
-
is_eager=True,
|
|
50
|
-
),
|
|
51
|
-
):
|
|
30
|
+
if value is not None:
|
|
31
|
+
loglevel = constants.LogLevel.from_string(value)
|
|
32
|
+
console.set_log_level(loglevel)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@click.group
|
|
36
|
+
@click.version_option(constants.Reflex.VERSION, message="%(version)s")
|
|
37
|
+
def cli():
|
|
52
38
|
"""Reflex CLI to create, run, and deploy apps."""
|
|
53
39
|
pass
|
|
54
40
|
|
|
55
41
|
|
|
42
|
+
loglevel_option = click.option(
|
|
43
|
+
"--loglevel",
|
|
44
|
+
type=click.Choice(
|
|
45
|
+
[loglevel.value for loglevel in constants.LogLevel],
|
|
46
|
+
case_sensitive=False,
|
|
47
|
+
),
|
|
48
|
+
is_eager=True,
|
|
49
|
+
callback=set_loglevel,
|
|
50
|
+
expose_value=False,
|
|
51
|
+
help="The log level to use.",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
56
55
|
def _init(
|
|
57
56
|
name: str,
|
|
58
57
|
template: str | None = None,
|
|
59
|
-
loglevel: constants.LogLevel | None = None,
|
|
60
58
|
ai: bool = False,
|
|
61
59
|
):
|
|
62
60
|
"""Initialize a new Reflex app in the given directory."""
|
|
63
61
|
from reflex.utils import exec, prerequisites
|
|
64
62
|
|
|
65
|
-
if loglevel is not None:
|
|
66
|
-
console.set_log_level(loglevel)
|
|
67
|
-
|
|
68
|
-
config = get_config()
|
|
69
|
-
|
|
70
|
-
# Set the log level.
|
|
71
|
-
loglevel = loglevel or config.loglevel
|
|
72
|
-
console.set_log_level(loglevel)
|
|
73
|
-
|
|
74
63
|
# Show system info
|
|
75
64
|
exec.output_system_info()
|
|
76
65
|
|
|
@@ -112,24 +101,28 @@ def _init(
|
|
|
112
101
|
|
|
113
102
|
|
|
114
103
|
@cli.command()
|
|
104
|
+
@loglevel_option
|
|
105
|
+
@click.option(
|
|
106
|
+
"--name",
|
|
107
|
+
metavar="APP_NAME",
|
|
108
|
+
help="The name of the app to initialize.",
|
|
109
|
+
)
|
|
110
|
+
@click.option(
|
|
111
|
+
"--template",
|
|
112
|
+
help="The template to initialize the app with.",
|
|
113
|
+
)
|
|
114
|
+
@click.option(
|
|
115
|
+
"--ai",
|
|
116
|
+
is_flag=True,
|
|
117
|
+
help="Use AI to create the initial template. Cannot be used with existing app or `--template` option.",
|
|
118
|
+
)
|
|
115
119
|
def init(
|
|
116
|
-
name: str
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
template: str = typer.Option(
|
|
120
|
-
None,
|
|
121
|
-
help="The template to initialize the app with.",
|
|
122
|
-
),
|
|
123
|
-
loglevel: constants.LogLevel | None = typer.Option(
|
|
124
|
-
None, help="The log level to use."
|
|
125
|
-
),
|
|
126
|
-
ai: bool = typer.Option(
|
|
127
|
-
False,
|
|
128
|
-
help="Use AI to create the initial template. Cannot be used with existing app or `--template` option.",
|
|
129
|
-
),
|
|
120
|
+
name: str,
|
|
121
|
+
template: str | None,
|
|
122
|
+
ai: bool,
|
|
130
123
|
):
|
|
131
124
|
"""Initialize a new Reflex app in the current directory."""
|
|
132
|
-
_init(name, template,
|
|
125
|
+
_init(name, template, ai)
|
|
133
126
|
|
|
134
127
|
|
|
135
128
|
def _run(
|
|
@@ -139,22 +132,14 @@ def _run(
|
|
|
139
132
|
frontend_port: int | None = None,
|
|
140
133
|
backend_port: int | None = None,
|
|
141
134
|
backend_host: str | None = None,
|
|
142
|
-
loglevel: constants.LogLevel | None = None,
|
|
143
135
|
):
|
|
144
136
|
"""Run the app in the given directory."""
|
|
145
137
|
from reflex.utils import build, exec, prerequisites, processes
|
|
146
138
|
|
|
147
|
-
if loglevel is not None:
|
|
148
|
-
console.set_log_level(loglevel)
|
|
149
|
-
|
|
150
139
|
config = get_config()
|
|
151
140
|
|
|
152
|
-
loglevel = loglevel or config.loglevel
|
|
153
141
|
backend_host = backend_host or config.backend_host
|
|
154
142
|
|
|
155
|
-
# Set the log level.
|
|
156
|
-
console.set_log_level(loglevel)
|
|
157
|
-
|
|
158
143
|
# Set env mode in the environment
|
|
159
144
|
environment.REFLEX_ENV_MODE.set(env)
|
|
160
145
|
|
|
@@ -168,7 +153,7 @@ def _run(
|
|
|
168
153
|
|
|
169
154
|
# Check that the app is initialized.
|
|
170
155
|
if prerequisites.needs_reinit(frontend=frontend):
|
|
171
|
-
_init(name=config.app_name
|
|
156
|
+
_init(name=config.app_name)
|
|
172
157
|
|
|
173
158
|
# Delete the states folder if it exists.
|
|
174
159
|
reset_disk_state_manager()
|
|
@@ -228,7 +213,7 @@ def _run(
|
|
|
228
213
|
else:
|
|
229
214
|
validation_result = app_task(*args)
|
|
230
215
|
if not validation_result:
|
|
231
|
-
raise
|
|
216
|
+
raise click.exceptions.Exit(1)
|
|
232
217
|
|
|
233
218
|
# Warn if schema is not up to date.
|
|
234
219
|
prerequisites.check_schema_up_to_date()
|
|
@@ -248,7 +233,7 @@ def _run(
|
|
|
248
233
|
exec.run_backend_prod,
|
|
249
234
|
)
|
|
250
235
|
if not setup_frontend or not frontend_cmd or not backend_cmd:
|
|
251
|
-
raise ValueError("Invalid env")
|
|
236
|
+
raise ValueError(f"Invalid env: {env}. Must be DEV or PROD.")
|
|
252
237
|
|
|
253
238
|
# Post a telemetry event.
|
|
254
239
|
telemetry.send(f"run-{env.value}")
|
|
@@ -271,7 +256,7 @@ def _run(
|
|
|
271
256
|
backend_cmd,
|
|
272
257
|
backend_host,
|
|
273
258
|
backend_port,
|
|
274
|
-
loglevel.subprocess_level(),
|
|
259
|
+
config.loglevel.subprocess_level(),
|
|
275
260
|
frontend,
|
|
276
261
|
)
|
|
277
262
|
)
|
|
@@ -281,7 +266,10 @@ def _run(
|
|
|
281
266
|
# In dev mode, run the backend on the main thread.
|
|
282
267
|
if backend and backend_port and env == constants.Env.DEV:
|
|
283
268
|
backend_cmd(
|
|
284
|
-
backend_host,
|
|
269
|
+
backend_host,
|
|
270
|
+
int(backend_port),
|
|
271
|
+
config.loglevel.subprocess_level(),
|
|
272
|
+
frontend,
|
|
285
273
|
)
|
|
286
274
|
# The windows uvicorn bug workaround
|
|
287
275
|
# https://github.com/reflex-dev/reflex/issues/2335
|
|
@@ -291,94 +279,123 @@ def _run(
|
|
|
291
279
|
|
|
292
280
|
|
|
293
281
|
@cli.command()
|
|
282
|
+
@loglevel_option
|
|
283
|
+
@click.option(
|
|
284
|
+
"--env",
|
|
285
|
+
type=click.Choice([e.value for e in constants.Env], case_sensitive=False),
|
|
286
|
+
default=constants.Env.DEV.value,
|
|
287
|
+
help="The environment to run the app in.",
|
|
288
|
+
)
|
|
289
|
+
@click.option(
|
|
290
|
+
"--frontend-only",
|
|
291
|
+
is_flag=True,
|
|
292
|
+
show_default=False,
|
|
293
|
+
help="Execute only frontend.",
|
|
294
|
+
envvar=environment.REFLEX_FRONTEND_ONLY.name,
|
|
295
|
+
)
|
|
296
|
+
@click.option(
|
|
297
|
+
"--backend-only",
|
|
298
|
+
is_flag=True,
|
|
299
|
+
show_default=False,
|
|
300
|
+
help="Execute only backend.",
|
|
301
|
+
envvar=environment.REFLEX_BACKEND_ONLY.name,
|
|
302
|
+
)
|
|
303
|
+
@click.option(
|
|
304
|
+
"--frontend-port",
|
|
305
|
+
type=int,
|
|
306
|
+
help="Specify a different frontend port.",
|
|
307
|
+
envvar=environment.REFLEX_FRONTEND_PORT.name,
|
|
308
|
+
)
|
|
309
|
+
@click.option(
|
|
310
|
+
"--backend-port",
|
|
311
|
+
type=int,
|
|
312
|
+
help="Specify a different backend port.",
|
|
313
|
+
envvar=environment.REFLEX_BACKEND_PORT.name,
|
|
314
|
+
)
|
|
315
|
+
@click.option(
|
|
316
|
+
"--backend-host",
|
|
317
|
+
help="Specify the backend host.",
|
|
318
|
+
)
|
|
294
319
|
def run(
|
|
295
|
-
env:
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
help="Execute only frontend.",
|
|
302
|
-
envvar=environment.REFLEX_FRONTEND_ONLY.name,
|
|
303
|
-
),
|
|
304
|
-
backend: bool = typer.Option(
|
|
305
|
-
False,
|
|
306
|
-
"--backend-only",
|
|
307
|
-
help="Execute only backend.",
|
|
308
|
-
envvar=environment.REFLEX_BACKEND_ONLY.name,
|
|
309
|
-
),
|
|
310
|
-
frontend_port: int | None = typer.Option(
|
|
311
|
-
None,
|
|
312
|
-
help="Specify a different frontend port.",
|
|
313
|
-
envvar=environment.REFLEX_FRONTEND_PORT.name,
|
|
314
|
-
),
|
|
315
|
-
backend_port: int | None = typer.Option(
|
|
316
|
-
None,
|
|
317
|
-
help="Specify a different backend port.",
|
|
318
|
-
envvar=environment.REFLEX_BACKEND_PORT.name,
|
|
319
|
-
),
|
|
320
|
-
backend_host: str | None = typer.Option(None, help="Specify the backend host."),
|
|
321
|
-
loglevel: constants.LogLevel | None = typer.Option(
|
|
322
|
-
None, help="The log level to use."
|
|
323
|
-
),
|
|
320
|
+
env: LITERAL_ENV,
|
|
321
|
+
frontend_only: bool,
|
|
322
|
+
backend_only: bool,
|
|
323
|
+
frontend_port: int | None,
|
|
324
|
+
backend_port: int | None,
|
|
325
|
+
backend_host: str | None,
|
|
324
326
|
):
|
|
325
327
|
"""Run the app in the current directory."""
|
|
326
|
-
if
|
|
328
|
+
if frontend_only and backend_only:
|
|
327
329
|
console.error("Cannot use both --frontend-only and --backend-only options.")
|
|
328
|
-
raise
|
|
329
|
-
|
|
330
|
-
if loglevel is not None:
|
|
331
|
-
console.set_log_level(loglevel)
|
|
330
|
+
raise click.exceptions.Exit(1)
|
|
332
331
|
|
|
333
332
|
config = get_config()
|
|
334
333
|
|
|
335
334
|
frontend_port = frontend_port or config.frontend_port
|
|
336
335
|
backend_port = backend_port or config.backend_port
|
|
337
336
|
backend_host = backend_host or config.backend_host
|
|
338
|
-
loglevel = loglevel or config.loglevel
|
|
339
337
|
|
|
340
338
|
environment.REFLEX_COMPILE_CONTEXT.set(constants.CompileContext.RUN)
|
|
341
|
-
environment.REFLEX_BACKEND_ONLY.set(
|
|
342
|
-
environment.REFLEX_FRONTEND_ONLY.set(
|
|
343
|
-
|
|
344
|
-
_run(
|
|
339
|
+
environment.REFLEX_BACKEND_ONLY.set(backend_only)
|
|
340
|
+
environment.REFLEX_FRONTEND_ONLY.set(frontend_only)
|
|
341
|
+
|
|
342
|
+
_run(
|
|
343
|
+
constants.Env.DEV if env == constants.Env.DEV else constants.Env.PROD,
|
|
344
|
+
frontend_only,
|
|
345
|
+
backend_only,
|
|
346
|
+
frontend_port,
|
|
347
|
+
backend_port,
|
|
348
|
+
backend_host,
|
|
349
|
+
)
|
|
345
350
|
|
|
346
351
|
|
|
347
352
|
@cli.command()
|
|
353
|
+
@loglevel_option
|
|
354
|
+
@click.option(
|
|
355
|
+
"--zip/--no-zip",
|
|
356
|
+
default=True,
|
|
357
|
+
is_flag=True,
|
|
358
|
+
help="Whether to zip the backend and frontend exports.",
|
|
359
|
+
)
|
|
360
|
+
@click.option(
|
|
361
|
+
"--frontend-only",
|
|
362
|
+
is_flag=True,
|
|
363
|
+
show_default=False,
|
|
364
|
+
envvar=environment.REFLEX_FRONTEND_ONLY.name,
|
|
365
|
+
help="Export only frontend.",
|
|
366
|
+
)
|
|
367
|
+
@click.option(
|
|
368
|
+
"--backend-only",
|
|
369
|
+
is_flag=True,
|
|
370
|
+
show_default=False,
|
|
371
|
+
envvar=environment.REFLEX_BACKEND_ONLY.name,
|
|
372
|
+
help="Export only backend.",
|
|
373
|
+
)
|
|
374
|
+
@click.option(
|
|
375
|
+
"--zip-dest-dir",
|
|
376
|
+
default=str(Path.cwd()),
|
|
377
|
+
help="The directory to export the zip files to.",
|
|
378
|
+
show_default=False,
|
|
379
|
+
)
|
|
380
|
+
@click.option(
|
|
381
|
+
"--upload-db-file",
|
|
382
|
+
is_flag=True,
|
|
383
|
+
help="Whether to exclude sqlite db files when exporting backend.",
|
|
384
|
+
hidden=True,
|
|
385
|
+
)
|
|
386
|
+
@click.option(
|
|
387
|
+
"--env",
|
|
388
|
+
type=click.Choice([e.value for e in constants.Env], case_sensitive=False),
|
|
389
|
+
default=constants.Env.PROD.value,
|
|
390
|
+
help="The environment to export the app in.",
|
|
391
|
+
)
|
|
348
392
|
def export(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
help="Export only frontend.",
|
|
356
|
-
show_default=False,
|
|
357
|
-
envvar=environment.REFLEX_FRONTEND_ONLY.name,
|
|
358
|
-
),
|
|
359
|
-
backend: bool = typer.Option(
|
|
360
|
-
False,
|
|
361
|
-
"--backend-only",
|
|
362
|
-
help="Export only backend.",
|
|
363
|
-
show_default=False,
|
|
364
|
-
envvar=environment.REFLEX_BACKEND_ONLY.name,
|
|
365
|
-
),
|
|
366
|
-
zip_dest_dir: str = typer.Option(
|
|
367
|
-
str(Path.cwd()),
|
|
368
|
-
help="The directory to export the zip files to.",
|
|
369
|
-
show_default=False,
|
|
370
|
-
),
|
|
371
|
-
upload_db_file: bool = typer.Option(
|
|
372
|
-
False,
|
|
373
|
-
help="Whether to exclude sqlite db files when exporting backend.",
|
|
374
|
-
hidden=True,
|
|
375
|
-
),
|
|
376
|
-
env: constants.Env = typer.Option(
|
|
377
|
-
constants.Env.PROD, help="The environment to export the app in."
|
|
378
|
-
),
|
|
379
|
-
loglevel: constants.LogLevel | None = typer.Option(
|
|
380
|
-
None, help="The log level to use."
|
|
381
|
-
),
|
|
393
|
+
zip: bool,
|
|
394
|
+
frontend_only: bool,
|
|
395
|
+
backend_only: bool,
|
|
396
|
+
zip_dest_dir: str,
|
|
397
|
+
upload_db_file: bool,
|
|
398
|
+
env: LITERAL_ENV,
|
|
382
399
|
):
|
|
383
400
|
"""Export the app to a zip file."""
|
|
384
401
|
from reflex.utils import export as export_utils
|
|
@@ -386,35 +403,33 @@ def export(
|
|
|
386
403
|
|
|
387
404
|
environment.REFLEX_COMPILE_CONTEXT.set(constants.CompileContext.EXPORT)
|
|
388
405
|
|
|
389
|
-
|
|
406
|
+
frontend_only, backend_only = prerequisites.check_running_mode(
|
|
407
|
+
frontend_only, backend_only
|
|
408
|
+
)
|
|
390
409
|
|
|
391
|
-
|
|
392
|
-
console.set_log_level(loglevel)
|
|
410
|
+
config = get_config()
|
|
393
411
|
|
|
394
|
-
if prerequisites.needs_reinit(frontend=
|
|
395
|
-
_init(name=
|
|
412
|
+
if prerequisites.needs_reinit(frontend=frontend_only or not backend_only):
|
|
413
|
+
_init(name=config.app_name)
|
|
396
414
|
|
|
397
415
|
export_utils.export(
|
|
398
|
-
zipping=
|
|
399
|
-
frontend=
|
|
400
|
-
backend=
|
|
416
|
+
zipping=zip,
|
|
417
|
+
frontend=frontend_only,
|
|
418
|
+
backend=backend_only,
|
|
401
419
|
zip_dest_dir=zip_dest_dir,
|
|
402
420
|
upload_db_file=upload_db_file,
|
|
403
|
-
env=env,
|
|
404
|
-
loglevel=loglevel.subprocess_level(),
|
|
421
|
+
env=constants.Env.DEV if env == constants.Env.DEV else constants.Env.PROD,
|
|
422
|
+
loglevel=config.loglevel.subprocess_level(),
|
|
405
423
|
)
|
|
406
424
|
|
|
407
425
|
|
|
408
426
|
@cli.command()
|
|
409
|
-
|
|
427
|
+
@loglevel_option
|
|
428
|
+
def login():
|
|
410
429
|
"""Authenticate with experimental Reflex hosting service."""
|
|
411
430
|
from reflex_cli.v2 import cli as hosting_cli
|
|
412
431
|
from reflex_cli.v2.deployments import check_version
|
|
413
432
|
|
|
414
|
-
loglevel = loglevel or get_config().loglevel
|
|
415
|
-
|
|
416
|
-
console.set_log_level(loglevel)
|
|
417
|
-
|
|
418
433
|
check_version()
|
|
419
434
|
|
|
420
435
|
validated_info = hosting_cli.login()
|
|
@@ -424,24 +439,27 @@ def login(loglevel: constants.LogLevel | None = typer.Option(None)):
|
|
|
424
439
|
|
|
425
440
|
|
|
426
441
|
@cli.command()
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
None, help="The log level to use."
|
|
430
|
-
),
|
|
431
|
-
):
|
|
442
|
+
@loglevel_option
|
|
443
|
+
def logout():
|
|
432
444
|
"""Log out of access to Reflex hosting service."""
|
|
433
445
|
from reflex_cli.v2.cli import logout
|
|
434
446
|
from reflex_cli.v2.deployments import check_version
|
|
435
447
|
|
|
436
448
|
check_version()
|
|
437
449
|
|
|
438
|
-
|
|
450
|
+
logout(_convert_reflex_loglevel_to_reflex_cli_loglevel(get_config().loglevel))
|
|
439
451
|
|
|
440
|
-
logout(_convert_reflex_loglevel_to_reflex_cli_loglevel(loglevel))
|
|
441
452
|
|
|
453
|
+
@click.group
|
|
454
|
+
def db_cli():
|
|
455
|
+
"""Subcommands for managing the database schema."""
|
|
456
|
+
pass
|
|
442
457
|
|
|
443
|
-
|
|
444
|
-
|
|
458
|
+
|
|
459
|
+
@click.group
|
|
460
|
+
def script_cli():
|
|
461
|
+
"""Subcommands for running helper scripts."""
|
|
462
|
+
pass
|
|
445
463
|
|
|
446
464
|
|
|
447
465
|
def _skip_compile():
|
|
@@ -495,11 +513,11 @@ def migrate():
|
|
|
495
513
|
|
|
496
514
|
|
|
497
515
|
@db_cli.command()
|
|
498
|
-
|
|
499
|
-
message
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
):
|
|
516
|
+
@click.option(
|
|
517
|
+
"--message",
|
|
518
|
+
help="Human readable identifier for the generated revision.",
|
|
519
|
+
)
|
|
520
|
+
def makemigrations(message: str | None):
|
|
503
521
|
"""Create autogenerated alembic migration scripts."""
|
|
504
522
|
from alembic.util.exc import CommandError
|
|
505
523
|
|
|
@@ -523,70 +541,74 @@ def makemigrations(
|
|
|
523
541
|
|
|
524
542
|
|
|
525
543
|
@cli.command()
|
|
544
|
+
@loglevel_option
|
|
545
|
+
@click.option(
|
|
546
|
+
"--app-name",
|
|
547
|
+
help="The name of the app to deploy.",
|
|
548
|
+
)
|
|
549
|
+
@click.option(
|
|
550
|
+
"--app-id",
|
|
551
|
+
help="The ID of the app to deploy.",
|
|
552
|
+
)
|
|
553
|
+
@click.option(
|
|
554
|
+
"-r",
|
|
555
|
+
"--region",
|
|
556
|
+
multiple=True,
|
|
557
|
+
help="The regions to deploy to. `reflex cloud regions` For multiple envs, repeat this option, e.g. --region sjc --region iad",
|
|
558
|
+
)
|
|
559
|
+
@click.option(
|
|
560
|
+
"--env",
|
|
561
|
+
multiple=True,
|
|
562
|
+
help="The environment variables to set: <key>=<value>. For multiple envs, repeat this option, e.g. --env k1=v2 --env k2=v2.",
|
|
563
|
+
)
|
|
564
|
+
@click.option(
|
|
565
|
+
"--vmtype",
|
|
566
|
+
help="Vm type id. Run `reflex cloud vmtypes` to get options.",
|
|
567
|
+
)
|
|
568
|
+
@click.option(
|
|
569
|
+
"--hostname",
|
|
570
|
+
help="The hostname of the frontend.",
|
|
571
|
+
)
|
|
572
|
+
@click.option(
|
|
573
|
+
"--interactive/--no-interactive",
|
|
574
|
+
is_flag=True,
|
|
575
|
+
default=True,
|
|
576
|
+
help="Whether to list configuration options and ask for confirmation.",
|
|
577
|
+
)
|
|
578
|
+
@click.option(
|
|
579
|
+
"--envfile",
|
|
580
|
+
help="The path to an env file to use. Will override any envs set manually.",
|
|
581
|
+
)
|
|
582
|
+
@click.option(
|
|
583
|
+
"--project",
|
|
584
|
+
help="project id to deploy to",
|
|
585
|
+
)
|
|
586
|
+
@click.option(
|
|
587
|
+
"--project-name",
|
|
588
|
+
help="The name of the project to deploy to.",
|
|
589
|
+
)
|
|
590
|
+
@click.option(
|
|
591
|
+
"--token",
|
|
592
|
+
help="token to use for auth",
|
|
593
|
+
)
|
|
594
|
+
@click.option(
|
|
595
|
+
"--config-path",
|
|
596
|
+
"--config",
|
|
597
|
+
help="path to the config file",
|
|
598
|
+
)
|
|
526
599
|
def deploy(
|
|
527
|
-
app_name: str | None
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
"-r",
|
|
540
|
-
"--region",
|
|
541
|
-
help="The regions to deploy to. `reflex cloud regions` For multiple envs, repeat this option, e.g. --region sjc --region iad",
|
|
542
|
-
),
|
|
543
|
-
envs: list[str] = typer.Option(
|
|
544
|
-
[],
|
|
545
|
-
"--env",
|
|
546
|
-
help="The environment variables to set: <key>=<value>. For multiple envs, repeat this option, e.g. --env k1=v2 --env k2=v2.",
|
|
547
|
-
),
|
|
548
|
-
vmtype: str | None = typer.Option(
|
|
549
|
-
None,
|
|
550
|
-
"--vmtype",
|
|
551
|
-
help="Vm type id. Run `reflex cloud vmtypes` to get options.",
|
|
552
|
-
),
|
|
553
|
-
hostname: str | None = typer.Option(
|
|
554
|
-
None,
|
|
555
|
-
"--hostname",
|
|
556
|
-
help="The hostname of the frontend.",
|
|
557
|
-
),
|
|
558
|
-
interactive: bool = typer.Option(
|
|
559
|
-
True,
|
|
560
|
-
help="Whether to list configuration options and ask for confirmation.",
|
|
561
|
-
),
|
|
562
|
-
envfile: str | None = typer.Option(
|
|
563
|
-
None,
|
|
564
|
-
"--envfile",
|
|
565
|
-
help="The path to an env file to use. Will override any envs set manually.",
|
|
566
|
-
),
|
|
567
|
-
loglevel: constants.LogLevel | None = typer.Option(
|
|
568
|
-
None, help="The log level to use."
|
|
569
|
-
),
|
|
570
|
-
project: str | None = typer.Option(
|
|
571
|
-
None,
|
|
572
|
-
"--project",
|
|
573
|
-
help="project id to deploy to",
|
|
574
|
-
),
|
|
575
|
-
project_name: str | None = typer.Option(
|
|
576
|
-
None,
|
|
577
|
-
"--project-name",
|
|
578
|
-
help="The name of the project to deploy to.",
|
|
579
|
-
),
|
|
580
|
-
token: str | None = typer.Option(
|
|
581
|
-
None,
|
|
582
|
-
"--token",
|
|
583
|
-
help="token to use for auth",
|
|
584
|
-
),
|
|
585
|
-
config_path: str | None = typer.Option(
|
|
586
|
-
None,
|
|
587
|
-
"--config",
|
|
588
|
-
help="path to the config file",
|
|
589
|
-
),
|
|
600
|
+
app_name: str | None,
|
|
601
|
+
app_id: str | None,
|
|
602
|
+
region: tuple[str, ...],
|
|
603
|
+
env: tuple[str],
|
|
604
|
+
vmtype: str | None,
|
|
605
|
+
hostname: str | None,
|
|
606
|
+
interactive: bool,
|
|
607
|
+
envfile: str | None,
|
|
608
|
+
project: str | None,
|
|
609
|
+
project_name: str | None,
|
|
610
|
+
token: str | None,
|
|
611
|
+
config_path: str | None,
|
|
590
612
|
):
|
|
591
613
|
"""Deploy the app to the Reflex hosting service."""
|
|
592
614
|
from reflex_cli.utils import dependency
|
|
@@ -596,21 +618,14 @@ def deploy(
|
|
|
596
618
|
from reflex.utils import export as export_utils
|
|
597
619
|
from reflex.utils import prerequisites
|
|
598
620
|
|
|
599
|
-
if loglevel is not None:
|
|
600
|
-
console.set_log_level(loglevel)
|
|
601
|
-
|
|
602
621
|
config = get_config()
|
|
603
622
|
|
|
604
|
-
loglevel = loglevel or config.loglevel
|
|
605
623
|
app_name = app_name or config.app_name
|
|
606
624
|
|
|
607
625
|
check_version()
|
|
608
626
|
|
|
609
627
|
environment.REFLEX_COMPILE_CONTEXT.set(constants.CompileContext.DEPLOY)
|
|
610
628
|
|
|
611
|
-
# Set the log level.
|
|
612
|
-
console.set_log_level(loglevel)
|
|
613
|
-
|
|
614
629
|
# Only check requirements if interactive.
|
|
615
630
|
# There is user interaction for requirements update.
|
|
616
631
|
if interactive:
|
|
@@ -618,7 +633,7 @@ def deploy(
|
|
|
618
633
|
|
|
619
634
|
# Check if we are set up.
|
|
620
635
|
if prerequisites.needs_reinit(frontend=True):
|
|
621
|
-
_init(name=config.app_name
|
|
636
|
+
_init(name=config.app_name)
|
|
622
637
|
prerequisites.check_latest_package_version(constants.ReflexHostingCLI.MODULE_NAME)
|
|
623
638
|
|
|
624
639
|
hosting_cli.deploy(
|
|
@@ -638,17 +653,17 @@ def deploy(
|
|
|
638
653
|
frontend=frontend,
|
|
639
654
|
backend=backend,
|
|
640
655
|
zipping=zipping,
|
|
641
|
-
loglevel=loglevel.subprocess_level(),
|
|
656
|
+
loglevel=config.loglevel.subprocess_level(),
|
|
642
657
|
upload_db_file=upload_db,
|
|
643
658
|
)
|
|
644
659
|
),
|
|
645
|
-
regions=
|
|
646
|
-
envs=
|
|
660
|
+
regions=list(region),
|
|
661
|
+
envs=list(env),
|
|
647
662
|
vmtype=vmtype,
|
|
648
663
|
envfile=envfile,
|
|
649
664
|
hostname=hostname,
|
|
650
665
|
interactive=interactive,
|
|
651
|
-
loglevel=_convert_reflex_loglevel_to_reflex_cli_loglevel(loglevel),
|
|
666
|
+
loglevel=_convert_reflex_loglevel_to_reflex_cli_loglevel(config.loglevel),
|
|
652
667
|
token=token,
|
|
653
668
|
project=project,
|
|
654
669
|
project_name=project_name,
|
|
@@ -657,19 +672,14 @@ def deploy(
|
|
|
657
672
|
|
|
658
673
|
|
|
659
674
|
@cli.command()
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
None, help="The log level to use."
|
|
664
|
-
),
|
|
665
|
-
):
|
|
675
|
+
@loglevel_option
|
|
676
|
+
@click.argument("new_name")
|
|
677
|
+
def rename(new_name: str):
|
|
666
678
|
"""Rename the app in the current directory."""
|
|
667
679
|
from reflex.utils import prerequisites
|
|
668
680
|
|
|
669
|
-
loglevel = loglevel or get_config().loglevel
|
|
670
|
-
|
|
671
681
|
prerequisites.validate_app_name(new_name)
|
|
672
|
-
prerequisites.rename_app(new_name, loglevel)
|
|
682
|
+
prerequisites.rename_app(new_name, get_config().loglevel)
|
|
673
683
|
|
|
674
684
|
|
|
675
685
|
if TYPE_CHECKING:
|
|
@@ -702,18 +712,20 @@ def _convert_reflex_loglevel_to_reflex_cli_loglevel(
|
|
|
702
712
|
return HostingLogLevel.INFO
|
|
703
713
|
|
|
704
714
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
hosting_cli,
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
)
|
|
715
|
+
if find_spec("typer"):
|
|
716
|
+
import typer # pyright: ignore[reportMissingImports]
|
|
717
|
+
|
|
718
|
+
if isinstance(hosting_cli, typer.Typer):
|
|
719
|
+
hosting_cli_command = typer.main.get_command(hosting_cli)
|
|
720
|
+
else:
|
|
721
|
+
hosting_cli_command = hosting_cli
|
|
722
|
+
else:
|
|
723
|
+
hosting_cli_command = hosting_cli
|
|
724
|
+
|
|
725
|
+
cli.add_command(hosting_cli_command, name="cloud")
|
|
726
|
+
cli.add_command(db_cli, name="db")
|
|
727
|
+
cli.add_command(script_cli, name="script")
|
|
728
|
+
cli.add_command(custom_components_cli, name="component")
|
|
717
729
|
|
|
718
730
|
if __name__ == "__main__":
|
|
719
731
|
cli()
|