Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to 0.2.6. #8

Merged
merged 2 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 37 additions & 26 deletions reflex/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import re
from enum import Enum
from types import SimpleNamespace
from typing import Optional

from platformdirs import PlatformDirs

Expand All @@ -18,6 +19,28 @@
IS_WINDOWS = platform.system() == "Windows"


def get_fnm_name() -> Optional[str]:
"""Get the appropriate fnm executable name based on the current platform.

Returns:
The fnm executable name for the current platform.
"""
platform_os = platform.system()

if platform_os == "Windows":
return "fnm-windows"
elif platform_os == "Darwin":
return "fnm-macos"
elif platform_os == "Linux":
machine = platform.machine()
if machine == "arm" or machine.startswith("armv7"):
return "fnm-arm32"
elif machine.startswith("aarch") or machine.startswith("armv8"):
return "fnm-arm64"
return "fnm-linux"
return None


# App names and versions.
# The name of the Reflex package.
MODULE_NAME = "reflex"
Expand All @@ -28,14 +51,9 @@
# The directory to store reflex dependencies.
REFLEX_DIR = (
# on windows, we use C:/Users/<username>/AppData/Local/reflex.
# on macOS, we use ~/Library/Application Support/reflex.
# on linux, we use ~/.local/share/reflex.
PlatformDirs(MODULE_NAME, False).user_data_dir
if IS_WINDOWS
else os.path.expandvars(
os.path.join(
"$HOME",
f".{MODULE_NAME}",
),
)
)
# The root directory of the reflex library.
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Expand All @@ -56,46 +74,39 @@
# Min Bun Version
MIN_BUN_VERSION = "0.7.0"
# The directory to store the bun.
BUN_ROOT_PATH = os.path.join(REFLEX_DIR, ".bun")
BUN_ROOT_PATH = os.path.join(REFLEX_DIR, "bun")
# Default bun path.
DEFAULT_BUN_PATH = os.path.join(BUN_ROOT_PATH, "bin", "bun")
# URL to bun install script.
BUN_INSTALL_URL = "https://bun.sh/install"

# NVM / Node config.
# The NVM version.
NVM_VERSION = "0.39.1"
# FNM / Node config.
# The FNM version.
FNM_VERSION = "1.35.1"
# The Node version.
NODE_VERSION = "18.17.0"
# The minimum required node version.
NODE_VERSION_MIN = "16.8.0"
# The directory to store nvm.
NVM_DIR = os.path.join(REFLEX_DIR, ".nvm")
# The directory to store fnm.
FNM_DIR = os.path.join(REFLEX_DIR, "fnm")
FNM_FILENAME = get_fnm_name()
# The fnm executable binary.
FNM_EXE = os.path.join(FNM_DIR, "fnm.exe")
# The nvm path.
NVM_PATH = os.path.join(NVM_DIR, "nvm.sh")
FNM_EXE = os.path.join(FNM_DIR, "fnm.exe" if IS_WINDOWS else "fnm")
# The node bin path.
NODE_BIN_PATH = (
os.path.join(NVM_DIR, "versions", "node", f"v{NODE_VERSION}", "bin")
if not IS_WINDOWS
else os.path.join(FNM_DIR, "node-versions", f"v{NODE_VERSION}", "installation")
NODE_BIN_PATH = os.path.join(
FNM_DIR,
"node-versions",
f"v{NODE_VERSION}",
"installation",
"bin" if not IS_WINDOWS else "",
)
# The default path where node is installed.
NODE_PATH = os.path.join(NODE_BIN_PATH, "node.exe" if IS_WINDOWS else "node")
# The default path where npm is installed.
NPM_PATH = os.path.join(NODE_BIN_PATH, "npm")
# The URL to the nvm install script.
NVM_INSTALL_URL = (
f"https://raw.githubusercontent.com/nvm-sh/nvm/v{NVM_VERSION}/install.sh"
)
# The URL to the fnm release binary
FNM_WINDOWS_INSTALL_URL = (
f"https://github.com/Schniz/fnm/releases/download/v{FNM_VERSION}/fnm-windows.zip"
FNM_INSTALL_URL = (
f"https://github.com/Schniz/fnm/releases/download/v{FNM_VERSION}/{FNM_FILENAME}.zip"
)
# The frontend directories in a project.
# The web folder where the NextJS app is compiled to.
Expand Down
29 changes: 24 additions & 5 deletions reflex/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,7 @@ def __init__(self, *args, parent_state: Optional[State] = None, **kwargs):
for substate in self.get_substates():
self.substates[substate.get_name()] = substate(parent_state=self)
# Convert the event handlers to functions.
for name, event_handler in self.event_handlers.items():
fn = functools.partial(event_handler.fn, self)
fn.__module__ = event_handler.fn.__module__ # type: ignore
fn.__qualname__ = event_handler.fn.__qualname__ # type: ignore
setattr(self, name, fn)
self._init_event_handlers()

# Initialize computed vars dependencies.
inherited_vars = set(self.inherited_vars).union(
Expand Down Expand Up @@ -155,6 +151,29 @@ def _init_mutable_fields(self):

self._clean()

def _init_event_handlers(self, state: State | None = None):
"""Initialize event handlers.

Allow event handlers to be called directly on the instance. This is
called recursively for all parent states.

Args:
state: The state to initialize the event handlers on.
"""
if state is None:
state = self

# Convert the event handlers to functions.
for name, event_handler in state.event_handlers.items():
fn = functools.partial(event_handler.fn, self)
fn.__module__ = event_handler.fn.__module__ # type: ignore
fn.__qualname__ = event_handler.fn.__qualname__ # type: ignore
setattr(self, name, fn)

# Also allow direct calling of parent state event handlers
if state.parent_state is not None:
self._init_event_handlers(state.parent_state)

def _reassign_field(self, field_name: str):
"""Reassign the given field.

Expand Down
19 changes: 11 additions & 8 deletions reflex/utils/exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ def run_frontend(
"""
# Start watching asset folder.
start_watching_assets_folder(root)
# validate dependencies before run
prerequisites.validate_frontend_dependencies(init=False)

# Run the frontend in development mode.
console.rule("[bold green]App Running")
os.environ["PORT"] = str(get_config().frontend_port if port is None else port)
run_process_and_launch_url([prerequisites.get_package_manager(), "run", "dev"])
run_process_and_launch_url([prerequisites.get_package_manager(), "run", "dev"]) # type: ignore


def run_frontend_prod(
Expand All @@ -77,10 +79,11 @@ def run_frontend_prod(
"""
# Set the port.
os.environ["PORT"] = str(get_config().frontend_port if port is None else port)

# validate dependencies before run
prerequisites.validate_frontend_dependencies(init=False)
# Run the frontend in production mode.
console.rule("[bold green]App Running")
run_process_and_launch_url([prerequisites.get_package_manager(), "run", "prod"])
run_process_and_launch_url([prerequisites.get_package_manager(), "run", "prod"]) # type: ignore


def run_backend(
Expand Down Expand Up @@ -155,7 +158,7 @@ def run_backend_prod(


def output_system_info():
"""Show system informations if the loglevel is in DEBUG."""
"""Show system information if the loglevel is in DEBUG."""
if console.LOG_LEVEL > constants.LogLevel.DEBUG:
return

Expand All @@ -171,15 +174,15 @@ def output_system_info():

dependencies = [
f"[Reflex {constants.VERSION} with Python {platform.python_version()} (PATH: {sys.executable})]",
f"[Node {prerequisites.get_node_version()} (Expected: {constants.NODE_VERSION}) (PATH:{constants.NODE_PATH})]",
f"[Node {prerequisites.get_node_version()} (Expected: {constants.NODE_VERSION}) (PATH:{path_ops.get_node_path()})]",
]

system = platform.system()

if system != "Windows":
dependencies.extend(
[
f"[NVM {constants.NVM_VERSION} (Expected: {constants.NVM_VERSION}) (PATH: {constants.NVM_PATH})]",
f"[FNM {constants.FNM_VERSION} (Expected: {constants.FNM_VERSION}) (PATH: {constants.FNM_EXE})]",
f"[Bun {prerequisites.get_bun_version()} (Expected: {constants.BUN_VERSION}) (PATH: {config.bun_path})]",
],
)
Expand All @@ -201,8 +204,8 @@ def output_system_info():
console.debug(f"{dep}")

console.debug(
f"Using package installer at: {prerequisites.get_install_package_manager()}"
f"Using package installer at: {prerequisites.get_install_package_manager()}" # type: ignore
)
console.debug(f"Using package executer at: {prerequisites.get_package_manager()}")
console.debug(f"Using package executer at: {prerequisites.get_package_manager()}") # type: ignore
if system != "Windows":
console.debug(f"Unzip path: {path_ops.which('unzip')}")
37 changes: 37 additions & 0 deletions reflex/utils/path_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

import os
import shutil
from pathlib import Path
from typing import Optional

from reflex import constants

# Shorthand for join.
join = os.linesep.join

Expand Down Expand Up @@ -107,3 +110,37 @@ def which(program: str) -> Optional[str]:
The path to the executable.
"""
return shutil.which(program)


def get_node_bin_path() -> Optional[str]:
"""Get the node binary dir path.

Returns:
The path to the node bin folder.
"""
if not os.path.exists(constants.NODE_BIN_PATH):
str_path = which("node")
return str(Path(str_path).parent) if str_path else str_path
return constants.NODE_BIN_PATH


def get_node_path() -> Optional[str]:
"""Get the node binary path.

Returns:
The path to the node binary file.
"""
if not os.path.exists(constants.NODE_PATH):
return which("node")
return constants.NODE_PATH


def get_npm_path() -> Optional[str]:
"""Get npm binary path.

Returns:
The path to the npm binary file.
"""
if not os.path.exists(constants.NODE_PATH):
return which("npm")
return constants.NPM_PATH
Loading