Skip to content

Commit 2152da1

Browse files
committed
Merge branch 'main' into release/masenf/bump-deps
2 parents fd309a5 + 7286076 commit 2152da1

File tree

24 files changed

+222
-86
lines changed

24 files changed

+222
-86
lines changed

.github/workflows/integration_app_harness.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ jobs:
4747
python-version: ${{ matrix.python-version }}
4848
run-poetry-install: true
4949
create-venv-at-path: .venv
50-
- run: poetry run uv pip install pyvirtualdisplay pillow pytest-split
50+
- run: poetry run uv pip install pyvirtualdisplay pillow pytest-split pytest-retry
5151
- name: Run app harness tests
5252
env:
5353
SCREENSHOT_DIR: /tmp/screenshots/${{ matrix.state_manager }}/${{ matrix.python-version }}/${{ matrix.split_index }}
5454
REDIS_URL: ${{ matrix.state_manager == 'redis' && 'redis://localhost:6379' || '' }}
5555
run: |
5656
poetry run playwright install chromium
57-
poetry run pytest tests/integration --splits 2 --group ${{matrix.split_index}}
57+
poetry run pytest tests/integration --retries 3 --maxfail=5 --splits 2 --group ${{matrix.split_index}}
5858
- uses: actions/upload-artifact@v4
5959
name: Upload failed test screenshots
6060
if: always()

reflex/.templates/web/utils/state.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import axios from "axios";
33
import io from "socket.io-client";
44
import JSON5 from "json5";
55
import env from "$/env.json";
6+
import reflexEnvironment from "$/reflex.json";
67
import Cookies from "universal-cookie";
78
import { useEffect, useRef, useState } from "react";
89
import Router, { useRouter } from "next/router";
@@ -407,6 +408,7 @@ export const connect = async (
407408
socket.current = io(endpoint.href, {
408409
path: endpoint["pathname"],
409410
transports: transports,
411+
protocols: env.TEST_MODE ? undefined : [reflexEnvironment.version],
410412
autoUnref: false,
411413
});
412414
// Ensure undefined fields in events are sent as null instead of removed

reflex/app.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -558,11 +558,12 @@ def add_page(
558558
meta=meta,
559559
)
560560

561-
def _compile_page(self, route: str):
561+
def _compile_page(self, route: str, save_page: bool = True):
562562
"""Compile a page.
563563
564564
Args:
565565
route: The route of the page to compile.
566+
save_page: If True, the compiled page is saved to self.pages.
566567
"""
567568
component, enable_state = compiler.compile_unevaluated_page(
568569
route, self.unevaluated_pages[route], self.state, self.style, self.theme
@@ -573,7 +574,8 @@ def _compile_page(self, route: str):
573574

574575
# Add the page.
575576
self._check_routes_conflict(route)
576-
self.pages[route] = component
577+
if save_page:
578+
self.pages[route] = component
577579

578580
def get_load_events(self, route: str) -> list[IndividualEventType[[], Any]]:
579581
"""Get the load events for a route.
@@ -873,14 +875,16 @@ def get_compilation_time() -> str:
873875
# If a theme component was provided, wrap the app with it
874876
app_wrappers[(20, "Theme")] = self.theme
875877

878+
should_compile = self._should_compile()
879+
876880
for route in self.unevaluated_pages:
877881
console.debug(f"Evaluating page: {route}")
878-
self._compile_page(route)
882+
self._compile_page(route, save_page=should_compile)
879883

880884
# Add the optional endpoints (_upload)
881885
self._add_optional_endpoints()
882886

883-
if not self._should_compile():
887+
if not should_compile:
884888
return
885889

886890
self._validate_var_dependencies()
@@ -1524,7 +1528,11 @@ def on_connect(self, sid, environ):
15241528
sid: The Socket.IO session id.
15251529
environ: The request information, including HTTP headers.
15261530
"""
1527-
pass
1531+
subprotocol = environ.get("HTTP_SEC_WEBSOCKET_PROTOCOL", None)
1532+
if subprotocol and subprotocol != constants.Reflex.VERSION:
1533+
console.warn(
1534+
f"Frontend version {subprotocol} for session {sid} does not match the backend version {constants.Reflex.VERSION}."
1535+
)
15281536

15291537
def on_disconnect(self, sid):
15301538
"""Event for when the websocket disconnects.

reflex/components/recharts/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
"Label",
7171
"label_list",
7272
"LabelList",
73+
"cell",
74+
"Cell",
7375
],
7476
"polar": [
7577
"pie",

reflex/components/recharts/__init__.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,13 @@ from .charts import radar_chart as radar_chart
5353
from .charts import radial_bar_chart as radial_bar_chart
5454
from .charts import scatter_chart as scatter_chart
5555
from .charts import treemap as treemap
56+
from .general import Cell as Cell
5657
from .general import GraphingTooltip as GraphingTooltip
5758
from .general import Label as Label
5859
from .general import LabelList as LabelList
5960
from .general import Legend as Legend
6061
from .general import ResponsiveContainer as ResponsiveContainer
62+
from .general import cell as cell
6163
from .general import graphing_tooltip as graphing_tooltip
6264
from .general import label as label
6365
from .general import label_list as label_list

reflex/components/recharts/general.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,23 @@ class LabelList(Recharts):
242242
stroke: Var[Union[str, Color]] = LiteralVar.create("none")
243243

244244

245+
class Cell(Recharts):
246+
"""A Cell component in Recharts."""
247+
248+
tag = "Cell"
249+
250+
alias = "RechartsCell"
251+
252+
# The presentation attribute of a rectangle in bar or a sector in pie.
253+
fill: Var[str]
254+
255+
# The presentation attribute of a rectangle in bar or a sector in pie.
256+
stroke: Var[str]
257+
258+
245259
responsive_container = ResponsiveContainer.create
246260
legend = Legend.create
247261
graphing_tooltip = GraphingTooltip.create
248262
label = Label.create
249263
label_list = LabelList.create
264+
cell = Cell.create

reflex/components/recharts/general.pyi

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,59 @@ class LabelList(Recharts):
482482
"""
483483
...
484484

485+
class Cell(Recharts):
486+
@overload
487+
@classmethod
488+
def create( # type: ignore
489+
cls,
490+
*children,
491+
fill: Optional[Union[Var[str], str]] = None,
492+
stroke: Optional[Union[Var[str], str]] = None,
493+
style: Optional[Style] = None,
494+
key: Optional[Any] = None,
495+
id: Optional[Any] = None,
496+
class_name: Optional[Any] = None,
497+
autofocus: Optional[bool] = None,
498+
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
499+
on_blur: Optional[EventType[[], BASE_STATE]] = None,
500+
on_click: Optional[EventType[[], BASE_STATE]] = None,
501+
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
502+
on_double_click: Optional[EventType[[], BASE_STATE]] = None,
503+
on_focus: Optional[EventType[[], BASE_STATE]] = None,
504+
on_mount: Optional[EventType[[], BASE_STATE]] = None,
505+
on_mouse_down: Optional[EventType[[], BASE_STATE]] = None,
506+
on_mouse_enter: Optional[EventType[[], BASE_STATE]] = None,
507+
on_mouse_leave: Optional[EventType[[], BASE_STATE]] = None,
508+
on_mouse_move: Optional[EventType[[], BASE_STATE]] = None,
509+
on_mouse_out: Optional[EventType[[], BASE_STATE]] = None,
510+
on_mouse_over: Optional[EventType[[], BASE_STATE]] = None,
511+
on_mouse_up: Optional[EventType[[], BASE_STATE]] = None,
512+
on_scroll: Optional[EventType[[], BASE_STATE]] = None,
513+
on_unmount: Optional[EventType[[], BASE_STATE]] = None,
514+
**props,
515+
) -> "Cell":
516+
"""Create the component.
517+
518+
Args:
519+
*children: The children of the component.
520+
fill: The presentation attribute of a rectangle in bar or a sector in pie.
521+
stroke: The presentation attribute of a rectangle in bar or a sector in pie.
522+
style: The style of the component.
523+
key: A unique key for the component.
524+
id: The id for the component.
525+
class_name: The class name for the component.
526+
autofocus: Whether the component should take the focus once the page is loaded
527+
custom_attrs: custom attribute
528+
**props: The props of the component.
529+
530+
Returns:
531+
The component.
532+
"""
533+
...
534+
485535
responsive_container = ResponsiveContainer.create
486536
legend = Legend.create
487537
graphing_tooltip = GraphingTooltip.create
488538
label = Label.create
489539
label_list = LabelList.create
540+
cell = Cell.create

reflex/constants/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""The constants package."""
22

33
from .base import (
4+
APP_HARNESS_FLAG,
45
COOKIES,
56
IS_LINUX,
67
IS_MACOS,

reflex/constants/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ class Ping(SimpleNamespace):
257257
# Testing variables.
258258
# Testing os env set by pytest when running a test case.
259259
PYTEST_CURRENT_TEST = "PYTEST_CURRENT_TEST"
260+
APP_HARNESS_FLAG = "APP_HARNESS_FLAG"
260261

261262
REFLEX_VAR_OPENING_TAG = "<reflex.Var>"
262263
REFLEX_VAR_CLOSING_TAG = "</reflex.Var>"

reflex/reflex.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,11 @@ def deploy(
440440
config.app_name,
441441
"--app-name",
442442
help="The name of the App to deploy under.",
443-
hidden=True,
443+
),
444+
app_id: str = typer.Option(
445+
None,
446+
"--app-id",
447+
help="The ID of the App to deploy over.",
444448
),
445449
regions: List[str] = typer.Option(
446450
[],
@@ -480,6 +484,11 @@ def deploy(
480484
"--project",
481485
help="project id to deploy to",
482486
),
487+
project_name: Optional[str] = typer.Option(
488+
None,
489+
"--project-name",
490+
help="The name of the project to deploy to.",
491+
),
483492
token: Optional[str] = typer.Option(
484493
None,
485494
"--token",
@@ -503,13 +512,6 @@ def deploy(
503512
# Set the log level.
504513
console.set_log_level(loglevel)
505514

506-
if not token:
507-
# make sure user is logged in.
508-
if interactive:
509-
hosting_cli.login()
510-
else:
511-
raise SystemExit("Token is required for non-interactive mode.")
512-
513515
# Only check requirements if interactive.
514516
# There is user interaction for requirements update.
515517
if interactive:
@@ -524,6 +526,7 @@ def deploy(
524526
)
525527
hosting_cli.deploy(
526528
app_name=app_name,
529+
app_id=app_id,
527530
export_fn=lambda zip_dest_dir,
528531
api_url,
529532
deploy_url,
@@ -547,6 +550,8 @@ def deploy(
547550
loglevel=type(loglevel).INFO, # type: ignore
548551
token=token,
549552
project=project,
553+
config_path=config_path,
554+
project_name=project_name,
550555
**extra,
551556
)
552557

0 commit comments

Comments
 (0)