Speed up reflex CLI imports (#2185)

This commit is contained in:
Nikhil Rao 2023-11-17 12:31:07 -08:00 committed by GitHub
parent 1a83f85783
commit c3e652b8c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 55 deletions

View File

@ -16,21 +16,11 @@ from typing import List, Optional
import typer
import typer.core
from alembic.util.exc import CommandError
from tabulate import tabulate
from reflex import constants, model
from reflex import constants
from reflex.config import get_config
from reflex.utils import (
build,
console,
dependency,
exec,
hosting,
prerequisites,
processes,
telemetry,
)
from reflex.utils import console, dependency, telemetry
# Disable typer+rich integration for help panels
typer.core.rich = False # type: ignore
@ -81,6 +71,8 @@ def _init(
loglevel: constants.LogLevel = config.loglevel,
):
"""Initialize a new Reflex app in the given directory."""
from reflex.utils import exec, prerequisites
# Set the log level.
console.set_log_level(loglevel)
@ -138,12 +130,14 @@ def _run(
env: constants.Env = constants.Env.DEV,
frontend: bool = True,
backend: bool = True,
frontend_port: str = str(get_config().frontend_port),
backend_port: str = str(get_config().backend_port),
frontend_port: str = str(config.frontend_port),
backend_port: str = str(config.backend_port),
backend_host: str = config.backend_host,
loglevel: constants.LogLevel = config.loglevel,
):
"""Run the app in the given directory."""
from reflex.utils import build, exec, prerequisites, processes
# Set the log level.
console.set_log_level(loglevel)
@ -279,10 +273,12 @@ def export(
hidden=True,
),
loglevel: constants.LogLevel = typer.Option(
console._LOG_LEVEL, help="The log level to use."
config.loglevel, help="The log level to use."
),
):
"""Export the app to a zip file."""
from reflex.utils import build, exec, prerequisites
# Set the log level.
console.set_log_level(loglevel)
@ -324,6 +320,8 @@ def login(
),
):
"""Authenticate with Reflex hosting service."""
from reflex.utils import hosting
# Set the log level.
console.set_log_level(loglevel)
@ -349,6 +347,8 @@ def logout(
),
):
"""Log out of access to Reflex hosting service."""
from reflex.utils import hosting
console.set_log_level(loglevel)
hosting.log_out_on_browser()
@ -367,6 +367,9 @@ def _skip_compile():
@db_cli.command(name="init")
def db_init():
"""Create database schema and migration configuration."""
from reflex import model
from reflex.utils import prerequisites
# Check the database url.
if config.db_url is None:
console.error("db_url is not configured, cannot initialize.")
@ -392,6 +395,9 @@ def db_init():
@db_cli.command()
def migrate():
"""Create or update database schema from migration scripts."""
from reflex import model
from reflex.utils import prerequisites
_skip_compile()
prerequisites.get_app()
if not prerequisites.check_db_initialized():
@ -407,6 +413,11 @@ def makemigrations(
),
):
"""Create autogenerated alembic migration scripts."""
from alembic.util.exc import CommandError
from reflex import model
from reflex.utils import prerequisites
_skip_compile()
prerequisites.get_app()
if not prerequisites.check_db_initialized():
@ -493,6 +504,8 @@ def deploy(
),
):
"""Deploy the app to the Reflex hosting service."""
from reflex.utils import hosting, prerequisites
# Set the log level.
console.set_log_level(loglevel)
@ -732,6 +745,8 @@ def list_deployments(
),
):
"""List all the hosted deployments of the authenticated user."""
from reflex.utils import hosting
console.set_log_level(loglevel)
try:
deployments = hosting.list_deployments()
@ -759,6 +774,8 @@ def delete_deployment(
),
):
"""Delete a hosted instance."""
from reflex.utils import hosting
console.set_log_level(loglevel)
try:
hosting.delete_deployment(key)
@ -776,6 +793,8 @@ def get_deployment_status(
),
):
"""Check the status of a deployment."""
from reflex.utils import hosting
console.set_log_level(loglevel)
try:
@ -812,6 +831,8 @@ def get_deployment_logs(
),
):
"""Get the logs for a deployment."""
from reflex.utils import hosting
console.set_log_level(loglevel)
console.print("Note: there is a few seconds delay for logs to be available.")
try:
@ -829,6 +850,8 @@ def get_deployment_build_logs(
),
):
"""Get the logs for a deployment."""
from reflex.utils import hosting
console.set_log_level(loglevel)
console.print("Note: there is a few seconds delay for logs to be available.")
@ -852,6 +875,8 @@ def get_deployment_regions(
),
):
"""List all the regions of the hosting service."""
from reflex.utils import hosting
console.set_log_level(loglevel)
list_regions_info = hosting.get_regions()
if as_json:

View File

@ -12,11 +12,10 @@ from pathlib import Path
from urllib.parse import urljoin
import psutil
import uvicorn
from reflex import constants
from reflex.config import get_config
from reflex.utils import console, path_ops, prerequisites, processes
from reflex.utils import console, path_ops
from reflex.utils.watch import AssetFolderWatch
@ -73,6 +72,8 @@ def run_process_and_launch_url(run_command: list[str]):
Args:
run_command: The command to run.
"""
from reflex.utils import processes
json_file_path = os.path.join(constants.Dirs.WEB, "package.json")
last_hash = detect_package_change(json_file_path)
process = None
@ -113,6 +114,8 @@ def run_frontend(root: Path, port: str):
root: The root path of the project.
port: The port to run the frontend on.
"""
from reflex.utils import prerequisites
# Start watching asset folder.
start_watching_assets_folder(root)
# validate dependencies before run
@ -131,6 +134,8 @@ def run_frontend_prod(root: Path, port: str):
root: The root path of the project (to keep same API as run_frontend).
port: The port to run the frontend on.
"""
from reflex.utils import prerequisites
# Set the port.
os.environ["PORT"] = str(get_config().frontend_port if port is None else port)
# validate dependencies before run
@ -152,6 +157,8 @@ def run_backend(
port: The app port
loglevel: The log level.
"""
import uvicorn
config = get_config()
app_module = f"{config.app_name}.{config.app_name}:{constants.CompileVars.APP}"
@ -183,6 +190,8 @@ def run_backend_prod(
port: The app port
loglevel: The log level.
"""
from reflex.utils import processes
num_workers = processes.get_num_workers()
config = get_config()
RUN_BACKEND_PROD = f"gunicorn --worker-class {config.gunicorn_worker_class} --preload --timeout {config.timeout} --log-level critical".split()
@ -227,6 +236,8 @@ def output_system_info():
if console._LOG_LEVEL > constants.LogLevel.DEBUG:
return
from reflex.utils import prerequisites
config = get_config()
try:
config_file = sys.modules[config.__module__].__file__

View File

@ -7,12 +7,9 @@ import multiprocessing
import platform
from datetime import datetime
import httpx
import psutil
from reflex import constants
from reflex.base import Base
from reflex.config import get_config
def get_os() -> str:
@ -60,16 +57,6 @@ def get_memory() -> int:
return psutil.virtual_memory().total >> 20
class Telemetry(Base):
"""Anonymous telemetry for Reflex."""
user_os: str = get_os()
cpu_count: int = get_cpu_count()
memory: int = get_memory()
reflex_version: str = get_reflex_version()
python_version: str = get_python_version()
def send(event: str, telemetry_enabled: bool | None = None) -> bool:
"""Send anonymous telemetry for Reflex.
@ -80,6 +67,10 @@ def send(event: str, telemetry_enabled: bool | None = None) -> bool:
Returns:
Whether the telemetry was sent successfully.
"""
import httpx
from reflex.config import get_config
# Get the telemetry_enabled from the config if it is not specified.
if telemetry_enabled is None:
telemetry_enabled = get_config().telemetry_enabled
@ -89,7 +80,6 @@ def send(event: str, telemetry_enabled: bool | None = None) -> bool:
return False
try:
telemetry = Telemetry()
with open(constants.Dirs.REFLEX_JSON) as f:
reflex_json = json.load(f)
distinct_id = reflex_json["project_hash"]
@ -98,11 +88,11 @@ def send(event: str, telemetry_enabled: bool | None = None) -> bool:
"event": event,
"properties": {
"distinct_id": distinct_id,
"user_os": telemetry.user_os,
"reflex_version": telemetry.reflex_version,
"python_version": telemetry.python_version,
"cpu_count": telemetry.cpu_count,
"memory": telemetry.memory,
"user_os": get_os(),
"reflex_version": get_reflex_version(),
"python_version": get_python_version(),
"cpu_count": get_cpu_count(),
"memory": get_memory(),
},
"timestamp": datetime.utcnow().isoformat(),
}

View File

@ -1,5 +1,3 @@
import json
from reflex.utils import telemetry
@ -9,32 +7,24 @@ def versiontuple(v):
def test_telemetry():
"""Test that telemetry is sent correctly."""
tel = telemetry.Telemetry()
# Check that the user OS is one of the supported operating systems.
assert tel.user_os is not None
assert tel.user_os in ["Linux", "Darwin", "Java", "Windows"]
user_os = telemetry.get_os()
assert user_os is not None
assert user_os in ["Linux", "Darwin", "Java", "Windows"]
# Check that the CPU count and memory are greater than 0.
assert tel.cpu_count > 0
assert telemetry.get_cpu_count() > 0
# Check that the available memory is greater than 0
assert tel.memory > 0
assert telemetry.get_memory() > 0
# Check that the Reflex version is not None.
assert tel.reflex_version is not None
assert telemetry.get_reflex_version() is not None
# Check that the Python version is greater than 3.7.
assert tel.python_version is not None
assert versiontuple(tel.python_version) >= versiontuple("3.7")
# Check the json method.
tel_json = json.loads(tel.json())
assert tel_json["user_os"] == tel.user_os
assert tel_json["cpu_count"] == tel.cpu_count
assert tel_json["memory"] == tel.memory
assert tel_json["reflex_version"] == tel.reflex_version
assert tel_json["python_version"] == tel.python_version
python_version = telemetry.get_python_version()
assert python_version is not None
assert versiontuple(python_version) >= versiontuple("3.7")
def test_disable():