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.

Files changed (44) hide show
  1. reflex/.templates/jinja/web/tailwind.config.js.jinja2 +65 -31
  2. reflex/.templates/web/utils/state.js +11 -1
  3. reflex/app.py +191 -87
  4. reflex/app_mixins/lifespan.py +2 -2
  5. reflex/compiler/compiler.py +31 -4
  6. reflex/components/base/body.pyi +3 -197
  7. reflex/components/base/link.pyi +4 -392
  8. reflex/components/base/meta.pyi +28 -608
  9. reflex/components/component.py +39 -57
  10. reflex/components/core/upload.py +8 -0
  11. reflex/components/dynamic.py +9 -1
  12. reflex/components/el/elements/metadata.pyi +0 -1
  13. reflex/components/markdown/markdown.py +0 -21
  14. reflex/components/markdown/markdown.pyi +2 -2
  15. reflex/components/radix/primitives/accordion.py +1 -1
  16. reflex/components/radix/primitives/form.py +1 -1
  17. reflex/components/radix/primitives/progress.py +1 -1
  18. reflex/components/radix/primitives/slider.py +1 -1
  19. reflex/components/radix/themes/color_mode.py +1 -1
  20. reflex/components/radix/themes/color_mode.pyi +1 -1
  21. reflex/components/radix/themes/layout/list.pyi +2 -391
  22. reflex/components/recharts/recharts.py +2 -2
  23. reflex/components/sonner/toast.py +1 -1
  24. reflex/config.py +4 -7
  25. reflex/constants/base.py +21 -0
  26. reflex/constants/installer.py +6 -6
  27. reflex/custom_components/custom_components.py +67 -64
  28. reflex/event.py +2 -0
  29. reflex/page.py +8 -0
  30. reflex/reflex.py +277 -265
  31. reflex/testing.py +30 -24
  32. reflex/utils/codespaces.py +6 -2
  33. reflex/utils/console.py +4 -3
  34. reflex/utils/exec.py +60 -24
  35. reflex/utils/format.py +17 -2
  36. reflex/utils/prerequisites.py +43 -30
  37. reflex/utils/processes.py +6 -6
  38. reflex/utils/types.py +11 -6
  39. reflex/vars/base.py +19 -1
  40. {reflex-0.7.8a1.dist-info → reflex-0.7.9a2.dist-info}/METADATA +6 -9
  41. {reflex-0.7.8a1.dist-info → reflex-0.7.9a2.dist-info}/RECORD +44 -44
  42. {reflex-0.7.8a1.dist-info → reflex-0.7.9a2.dist-info}/WHEEL +0 -0
  43. {reflex-0.7.8a1.dist-info → reflex-0.7.9a2.dist-info}/entry_points.txt +0 -0
  44. {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 typer
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
- # Create the app.
24
- cli = typer.Typer(add_completion=False, pretty_exceptions_enable=False)
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
- value: Whether the version flag was passed.
32
-
33
- Raises:
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
- console.print(constants.Reflex.VERSION)
38
- raise typer.Exit()
39
-
40
-
41
- @cli.callback()
42
- def main(
43
- version: bool = typer.Option(
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 = typer.Option(
117
- None, metavar="APP_NAME", help="The name of the app to initialize."
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, loglevel, ai)
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, loglevel=loglevel)
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 typer.Exit(1)
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, int(backend_port), loglevel.subprocess_level(), frontend
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: constants.Env = typer.Option(
296
- constants.Env.DEV, help="The environment to run the app in."
297
- ),
298
- frontend: bool = typer.Option(
299
- False,
300
- "--frontend-only",
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 frontend and backend:
328
+ if frontend_only and backend_only:
327
329
  console.error("Cannot use both --frontend-only and --backend-only options.")
328
- raise typer.Exit(1)
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(backend)
342
- environment.REFLEX_FRONTEND_ONLY.set(frontend)
343
-
344
- _run(env, frontend, backend, frontend_port, backend_port, backend_host, loglevel)
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
- zipping: bool = typer.Option(
350
- True, "--no-zip", help="Disable zip for backend and frontend exports."
351
- ),
352
- frontend: bool = typer.Option(
353
- False,
354
- "--frontend-only",
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
- frontend, backend = prerequisites.check_running_mode(frontend, backend)
406
+ frontend_only, backend_only = prerequisites.check_running_mode(
407
+ frontend_only, backend_only
408
+ )
390
409
 
391
- loglevel = loglevel or get_config().loglevel
392
- console.set_log_level(loglevel)
410
+ config = get_config()
393
411
 
394
- if prerequisites.needs_reinit(frontend=frontend or not backend):
395
- _init(name=get_config().app_name, loglevel=loglevel)
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=zipping,
399
- frontend=frontend,
400
- backend=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
- def login(loglevel: constants.LogLevel | None = typer.Option(None)):
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
- def logout(
428
- loglevel: constants.LogLevel | None = typer.Option(
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
- loglevel = loglevel or get_config().loglevel
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
- db_cli = typer.Typer()
444
- script_cli = typer.Typer()
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
- def makemigrations(
499
- message: str = typer.Option(
500
- None, help="Human readable identifier for the generated revision."
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 = typer.Option(
528
- None,
529
- "--app-name",
530
- help="The name of the App to deploy under.",
531
- ),
532
- app_id: str = typer.Option(
533
- None,
534
- "--app-id",
535
- help="The ID of the App to deploy over.",
536
- ),
537
- regions: list[str] = typer.Option(
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, loglevel=loglevel)
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=regions,
646
- envs=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
- def rename(
661
- new_name: str = typer.Argument(..., help="The new name for the app."),
662
- loglevel: constants.LogLevel | None = typer.Option(
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
- cli.add_typer(db_cli, name="db", help="Subcommands for managing the database schema.")
706
- cli.add_typer(script_cli, name="script", help="Subcommands running helper scripts.")
707
- cli.add_typer(
708
- hosting_cli,
709
- name="cloud",
710
- help="Subcommands for managing the reflex cloud.",
711
- )
712
- cli.add_typer(
713
- custom_components_cli,
714
- name="component",
715
- help="Subcommands for creating and publishing Custom Components.",
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()