Pārlūkot izejas kodu

Merge branch 'develop' into docs/list-of-value-docs

namnguyen 6 mēneši atpakaļ
vecāks
revīzija
0a69c7bdf0

+ 2 - 2
.github/workflows/dependencies-management.yml

@@ -1,5 +1,5 @@
 # This workflow is used to manage the dependencies of the Taipy packages.
-# - Runs each Sunday.
+# - Runs every 2 weeks on Sundays.
 # - For each Python version supported:
 #   - Call a custom script to align dependencies between Taipy packages.
 #   - Call a custom script to update dependencies (Pipfile and requirements.txt).
@@ -12,7 +12,7 @@ name: Dependencies management
 
 on:
   schedule:
-    # Run every 2 weeks on Sunday at mid day UTC
+    # Run every 2 weeks on Sunday at midday UTC
     - cron: 00 12 */14 * 0
 
   workflow_dispatch:

+ 3 - 3
.github/workflows/partial-tests.yml

@@ -56,7 +56,7 @@ jobs:
         run: pip install --upgrade setuptools wheel
 
       - name: Install pipenv
-        run: pip install --upgrade pipenv
+        run: pip install pipenv --upgrade
 
       - name: Install Dependencies
         run: pipenv install --dev --python=${{ matrix.python-version }}
@@ -154,7 +154,7 @@ jobs:
 
       - name: Install pipenv
         if: steps.changes.outputs.core == 'true'
-        run: pip install --upgrade pipenv
+        run: pip install pipenv --upgrade
 
       - name: Install Dependencies
         if: steps.changes.outputs.core == 'true'
@@ -197,7 +197,7 @@ jobs:
 
       - name: Install pipenv
         if: steps.changes.outputs.core == 'true'
-        run: pip install --upgrade pipenv
+        run: pip install pipenv --upgrade
 
       - name: Install Dependencies
         if: steps.changes.outputs.core == 'true'

+ 3 - 3
Pipfile

@@ -8,9 +8,9 @@ apispec = {extras = ["yaml"], version = "==6.3"}
 apispec-webframeworks = "==0.5.2"
 cookiecutter = "==2.1.1"
 deepdiff = "==6.7.1"
-flask = "==3.0.0"
+flask = "==3.1.0"
 flask-cors = "==5.0.0"
-flask-socketio = "==5.3.6"
+flask-socketio = "==5.4.1"
 Flask-RESTful = ">=0.3.9"
 gevent = "==24.11.1"
 gevent-websocket = "==0.10.1"
@@ -21,7 +21,7 @@ marshmallow = "==3.20.1"
 networkx = "==2.6"
 openpyxl = "==3.1.2"
 pandas = "==1.3.5"
-pyarrow = "*"
+pyarrow = "==16.0.0"
 pymongo = {extras = ["srv"], version = "==4.6.3"}
 python-dotenv = "==1.0.0"
 python-magic = {version = "==0.4.24", markers="sys_platform != 'win32'"}

+ 23 - 0
doc/gui/examples/controls/button_size.py

@@ -0,0 +1,23 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+page = """
+ <|Button Label|button|size=large|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Button - Size")

+ 23 - 0
doc/gui/examples/controls/button_variant.py

@@ -0,0 +1,23 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+# -----------------------------------------------------------------------------------------
+# To execute this script, make sure that the taipy-gui package is installed in your
+# Python environment and run:
+#     python <script>
+# -----------------------------------------------------------------------------------------
+from taipy.gui import Gui
+
+page = """
+ <|Button Label|button|variant=contained|>
+"""
+
+if __name__ == "__main__":
+    Gui(page).run(title="Button - Variant")

+ 1 - 1
doc/gui/examples/controls/table_guard_edits.py

@@ -88,7 +88,7 @@ def check_add(state: State, var_name: str, payload: dict):
 def force_salary(state: State, var_name: str, payload: dict):
     # Get the salary proposal from the callback's payload
     proposed_salary = payload["value"]
-    # Round it the the nearest multiple of 5000
+    # Round it to the nearest multiple of 5000
     proposed_salary = round(proposed_salary / 500) * 500
     # Set it as the value to be stored in the dataset
     payload["value"] = proposed_salary

+ 19 - 0
frontend/taipy-gui/src/components/Taipy/Button.spec.tsx

@@ -70,6 +70,25 @@ describe("Button Component", () => {
         const elt = getByText("val");
         expect(elt).not.toBeDisabled();
     });
+    it("renders with default properties",()=>{
+        const {getByRole} = render(<Button label="val"/>);
+        const elt = getByRole("button");
+        expect(elt).toBeInTheDocument();
+        expect(elt).toHaveClass("MuiButton-sizeMedium");
+        expect(elt).toHaveClass("MuiButton-outlinedPrimary");
+    });
+    it("applies correct size",()=>{
+        const {getByRole}=render(<Button label="val" size="large"/>);
+        const elt = getByRole("button");
+        expect(elt).toBeInTheDocument();
+        expect(elt).toHaveClass("MuiButton-sizeLarge");
+    });
+    it("applies correct variant",()=>{
+        const {getByRole}=render(<Button label="val" variant="text"/>);
+        const elt=getByRole("button");
+        expect(elt).toBeInTheDocument();
+        expect(elt).toHaveClass("MuiButton-textPrimary");
+    });
     it("dispatch a well formed message", async () => {
         const dispatch = jest.fn();
         const state: TaipyState = INITIAL_STATE;

+ 5 - 3
frontend/taipy-gui/src/components/Taipy/Button.tsx

@@ -27,12 +27,14 @@ interface ButtonProps extends TaipyActiveProps {
     label: string;
     defaultLabel?: string;
     width?: string | number;
+    size?: "small" | "medium" | "large";
+    variant?: "text" | "outlined" | "contained";
 }
 
 const cardSx = { p: 0 };
 
 const Button = (props: ButtonProps) => {
-    const { id, onAction = "", defaultLabel } = props;
+    const { id, onAction = "", defaultLabel, size = "medium", variant = "outlined" } = props;
     const [value, setValue] = useState<stringIcon>("");
     const dispatch = useDispatch();
     const module = useModule();
@@ -40,7 +42,6 @@ const Button = (props: ButtonProps) => {
     const className = useClassNames(props.libClassName, props.dynamicClassName, props.className);
     const active = useDynamicProperty(props.active, props.defaultActive, true);
     const hover = useDynamicProperty(props.hoverText, props.defaultHoverText, undefined);
-
     const buttonSx = useMemo(() => (props.width ? { width: getCssSize(props.width) } : undefined), [props.width]);
 
     const handleClick = useCallback(() => {
@@ -67,7 +68,8 @@ const Button = (props: ButtonProps) => {
         <Tooltip title={hover || ""}>
             <MuiButton
                 id={id}
-                variant="outlined"
+                variant={variant}
+                size={size}
                 className={`${className} ${getComponentClassName(props.children)}`}
                 onClick={handleClick}
                 disabled={!active}

+ 1 - 1
pyproject.toml

@@ -29,7 +29,7 @@ image = [
     "python-magic-bin>=0.4.14,<0.5",
 ]
 rdp = ["rdp>=0.8"]
-arrow = ["pyarrow>=17.0.0,<18.0"]
+arrow = ["pyarrow>=16.0.0,<19.0"]
 mssql = ["pyodbc>=4"]
 
 [project.scripts]

+ 1 - 1
setup.py

@@ -56,7 +56,7 @@ setup(
             "python-magic-bin>=0.4.14,<0.5;platform_system=='Windows'",
         ],
         "rdp": ["rdp>=0.8"],
-        "arrow": ["pyarrow>=16.0.0,<18.0"],
+        "arrow": ["pyarrow>=16.0.0,<19.0"],
         "mssql": ["pyodbc>=4"],
     },
     cmdclass={"build_py": NPMInstall},

+ 1 - 2
taipy/core/_entity/_entity.py

@@ -33,8 +33,7 @@ class _Entity:
             for to_delete_key in self._properties._pending_deletions:
                 self._properties.data.pop(to_delete_key, None)
             self._properties.data.update(self._properties._pending_changes)
-        _Reloader._get_manager(self._MANAGER_NAME)._set(self)
+        _Reloader()._get_manager(self._MANAGER_NAME)._set(self)
 
         for event in self._in_context_attributes_changed_collector:
             Notifier.publish(event)
-        _Reloader._get_manager(self._MANAGER_NAME)._set(self)

+ 1 - 2
taipy/core/_entity/_reload.py

@@ -104,7 +104,6 @@ def _self_setter(manager):
         @functools.wraps(fct)
         def _do_set_entity(self, *args, **kwargs):
             fct(self, *args, **kwargs)
-            entity_manager = _Reloader._get_manager(manager)
             value = args[0] if len(args) == 1 else args
             event = _make_event(
                 self,
@@ -115,7 +114,7 @@ def _self_setter(manager):
             if not self._is_in_context:
                 entity = _Reloader()._reload(manager, self)
                 fct(entity, *args, **kwargs)
-                entity_manager._set(entity)
+                _Reloader._get_manager(manager)._set(entity)
                 Notifier.publish(event)
             else:
                 self._in_context_attributes_changed_collector.append(event)

+ 1 - 1
taipy/core/pyproject.toml

@@ -26,7 +26,7 @@ dynamic = ["version", "dependencies"]
 mssql = ["pyodbc>=4,<4.1"]
 mysql = ["pymysql>1,<1.1"]
 postgresql = ["psycopg2>2.9,<2.10"]
-parquet = ["fastparquet==2022.11.0", "pyarrow>=17.0.0,<18.0"]
+parquet = ["fastparquet==2022.11.0", "pyarrow>=16.0.0,<19.0"]
 s3 = ["boto3==1.29.1"]
 mongo = ["pymongo[srv]>=4.2.0,<5.0"]
 

+ 1 - 1
taipy/core/setup.py

@@ -43,7 +43,7 @@ extras_require = {
     "mssql": ["pyodbc>=4,<4.1"],
     "mysql": ["pymysql>1,<1.1"],
     "postgresql": ["psycopg2>2.9,<2.10"],
-    "parquet": ["fastparquet==2022.11.0", "pyarrow>=17.0.0,<18.0"],
+    "parquet": ["fastparquet==2022.11.0", "pyarrow>=16.0.0,<19.0"],
     "s3": ["boto3==1.29.1"],
     "mongo": ["pymongo[srv]>=4.2.0,<5.0"],
 }

+ 2 - 0
taipy/gui/_renderers/factory.py

@@ -99,6 +99,8 @@ class _Factory:
                 ("active", PropertyType.dynamic_boolean, True),
                 ("hover_text", PropertyType.dynamic_string),
                 ("width", PropertyType.string_or_number),
+                ("size", PropertyType.string),
+                ("variant", PropertyType.string),
             ]
         ),
         "chat": lambda gui, control_type, attrs: _Builder(

+ 1 - 1
taipy/gui/pyproject.toml

@@ -28,7 +28,7 @@ image = [
     "python-magic>=0.4.24,<0.5;platform_system!='Windows'",
     "python-magic-bin>=0.4.14,<0.5;platform_system=='Windows'",
 ]
-arrow = ["pyarrow>=17.0.0,<18.0"]
+arrow = ["pyarrow>=16.0.0,<19.0"]
 
 [tool.setuptools.packages]
 find = {include = ["taipy", "taipy.gui", "taipy.gui.*"]}

+ 1 - 1
taipy/gui/setup.py

@@ -45,7 +45,7 @@ extras_require = {
         "python-magic>=0.4.24,<0.5;platform_system!='Windows'",
         "python-magic-bin>=0.4.14,<0.5;platform_system=='Windows'",
     ],
-    "arrow": ["pyarrow>=17.0.0,<18.0"],
+    "arrow": ["pyarrow>=16.0.0,<19.0"],
 }
 
 def _build_webapp():

+ 2 - 0
taipy/gui/utils/_evaluator.py

@@ -256,6 +256,8 @@ class _Evaluator:
             # evaluate expressions
             ctx: t.Dict[str, t.Any] = {}
             ctx.update(self.__global_ctx)
+            if lambda_expr:
+                ctx.update(gui._get_locals_bind())
             # entries in var_val are not always seen (NameError) when passed as locals
             ctx.update(var_val)
             with gui._get_authorization():

+ 11 - 0
taipy/gui/viselements.json

@@ -53,6 +53,17 @@
                         "type": "dynamic(Union[str,Icon])",
                         "default_value": "\"\"",
                         "doc": "The label displayed in the button."
+                    },                                        {
+                    "name": "size",
+                        "type": "str",
+                        "default_value": "\"medium\"",
+                        "doc": "The size of the button. Valid values: \"small\", \"medium\", or \"large\"."
+                    },
+                    {
+                        "name": "variant",
+                        "type": "str",
+                        "default_value": "\"outlined\"",
+                        "doc": "The variant of the button. Valid values: \"contained\", \"outlined\", or \"text\"."
                     },
                     {
                         "name": "on_action",

+ 25 - 0
tests/gui/gui_specific/test_evaluator.py

@@ -0,0 +1,25 @@
+# Copyright 2021-2024 Avaiga Private Limited
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+
+from taipy.gui import Gui
+from taipy.gui.utils._evaluator import _Evaluator
+
+
+def _identity(x):
+    return x
+
+def test_evaluate_expr_lambda_from_element(gui: Gui, test_client, helpers):
+    gui._Gui__evaluator = _Evaluator({}, []) # type: ignore[attr-defined]
+    gui._Gui__locals_context.add("a_module", {"identity": _identity}) # type: ignore[attr-defined]
+    with gui._set_locals_context("a_module"):
+        evaluated_expr: str = gui._evaluate_expr("lambda x: identity(x)", lambda_expr=True)
+        assert evaluated_expr.startswith("__lambda_")
+        assert evaluated_expr.endswith("_TPMDL_0")

+ 4 - 4
tools/packages/pipfiles/Pipfile3.10.max

@@ -50,7 +50,7 @@ version = "==4.2.13"
 
 
 [packages]
-"pyarrow" = {version="==17.0.0"}
+"pyarrow" = {version="==18.0.0"}
 "networkx" = {version="==3.3", markers="python_version>'3.8'"}
 "openpyxl" = {version="==3.1.2"}
 "pandas" = {version="==2.2.2", markers="python_version>'3.8'"}
@@ -59,14 +59,14 @@ version = "==4.2.13"
 "toml" = {version="==0.10.2"}
 "boto3" = {version="==1.34.113"}
 "cookiecutter" = {version="==2.6.0"}
-"flask" = {version="==3.0.3"}
+"flask" = {version="==3.1.0"}
 "flask-cors" = {version="==5.0.0"}
-"flask-socketio" = {version="==5.3.6"}
+"flask-socketio" = {version="==5.4.1"}
 "markdown" = {version="==3.6"}
 "python-dotenv" = {version="==1.0.1"}
 "pytz" = {version="==2024.1"}
 "tzlocal" = {version="==5.2"}
-"gevent" = {version="==24.2.1"}
+"gevent" = {version="==24.11.1"}
 "gevent-websocket" = {version="==0.10.1"}
 "kthread" = {version="==0.2.3"}
 "gitignore-parser" = {version="==0.1.11"}

+ 4 - 4
tools/packages/pipfiles/Pipfile3.11.max

@@ -50,7 +50,7 @@ version = "==4.2.13"
 
 
 [packages]
-"pyarrow" = {version="==17.0.0"}
+"pyarrow" = {version="==18.0.0"}
 "networkx" = {version="==3.3", markers="python_version>'3.8'"}
 "openpyxl" = {version="==3.1.2"}
 "pandas" = {version="==2.2.2", markers="python_version>'3.8'"}
@@ -59,14 +59,14 @@ version = "==4.2.13"
 "toml" = {version="==0.10.2"}
 "boto3" = {version="==1.34.113"}
 "cookiecutter" = {version="==2.6.0"}
-"flask" = {version="==3.0.3"}
+"flask" = {version="==3.1.0"}
 "flask-cors" = {version="==5.0.0"}
-"flask-socketio" = {version="==5.3.6"}
+"flask-socketio" = {version="==5.4.1"}
 "markdown" = {version="==3.6"}
 "python-dotenv" = {version="==1.0.1"}
 "pytz" = {version="==2024.1"}
 "tzlocal" = {version="==5.2"}
-"gevent" = {version="==24.2.1"}
+"gevent" = {version="==24.11.1"}
 "gevent-websocket" = {version="==0.10.1"}
 "kthread" = {version="==0.2.3"}
 "gitignore-parser" = {version="==0.1.11"}

+ 4 - 4
tools/packages/pipfiles/Pipfile3.12.max

@@ -50,7 +50,7 @@ version = "==4.2.13"
 
 
 [packages]
-"pyarrow" = {version="==17.0.0"}
+"pyarrow" = {version="==18.0.0"}
 "networkx" = {version="==3.3", markers="python_version>'3.8'"}
 "openpyxl" = {version="==3.1.2"}
 "pandas" = {version="==2.2.2", markers="python_version>'3.8'"}
@@ -59,14 +59,14 @@ version = "==4.2.13"
 "toml" = {version="==0.10.2"}
 "boto3" = {version="==1.34.113"}
 "cookiecutter" = {version="==2.6.0"}
-"flask" = {version="==3.0.3"}
+"flask" = {version="==3.1.0"}
 "flask-cors" = {version="==5.0.0"}
-"flask-socketio" = {version="==5.3.6"}
+"flask-socketio" = {version="==5.4.1"}
 "markdown" = {version="==3.6"}
 "python-dotenv" = {version="==1.0.1"}
 "pytz" = {version="==2024.1"}
 "tzlocal" = {version="==5.2"}
-"gevent" = {version="==24.2.1"}
+"gevent" = {version="==24.11.1"}
 "gevent-websocket" = {version="==0.10.1"}
 "kthread" = {version="==0.2.3"}
 "gitignore-parser" = {version="==0.1.11"}

+ 4 - 4
tools/packages/pipfiles/Pipfile3.9.max

@@ -50,7 +50,7 @@ version = "==4.2.13"
 
 
 [packages]
-"pyarrow" = {version="==17.0.0"}
+"pyarrow" = {version="==18.0.0"}
 "networkx" = {version="==3.2.1", markers="python_version>'3.8'"}
 "openpyxl" = {version="==3.1.2"}
 "pandas" = {version="==2.2.2", markers="python_version>'3.8'"}
@@ -59,14 +59,14 @@ version = "==4.2.13"
 "toml" = {version="==0.10.2"}
 "boto3" = {version="==1.34.113"}
 "cookiecutter" = {version="==2.6.0"}
-"flask" = {version="==3.0.3"}
+"flask" = {version="==3.1.0"}
 "flask-cors" = {version="==5.0.0"}
-"flask-socketio" = {version="==5.3.6"}
+"flask-socketio" = {version="==5.4.1"}
 "markdown" = {version="==3.6"}
 "python-dotenv" = {version="==1.0.1"}
 "pytz" = {version="==2024.1"}
 "tzlocal" = {version="==5.2"}
-"gevent" = {version="==24.2.1"}
+"gevent" = {version="==24.11.1"}
 "gevent-websocket" = {version="==0.10.1"}
 "kthread" = {version="==0.2.3"}
 "gitignore-parser" = {version="==0.1.11"}

+ 1 - 1
tools/packages/taipy-core/setup.requirements.txt

@@ -2,7 +2,7 @@ boto3>=1.29.4,<=1.34.113
 networkx>=2.6,<=3.3
 openpyxl>=3.1.2,<=3.1.2
 pandas>=1.3.5,<=2.2.2
-pyarrow>=17.0.0,<=17.9.9
+pyarrow>=16.0.0,<19.0
 pymongo[srv]>=4.2.0,<=4.7.2
 sqlalchemy>=2.0.16,<=2.0.30
 taipy-common

+ 1 - 1
tools/packages/taipy-gui/setup.py

@@ -44,7 +44,7 @@ extras_require = {
         "python-magic>=0.4.24,<0.5;platform_system!='Windows'",
         "python-magic-bin>=0.4.14,<0.5;platform_system=='Windows'",
     ],
-    "arrow": ["pyarrow>=17.0.0,<18.0"],
+    "arrow": ["pyarrow>=16.0.0,<19.0"],
 }
 
 

+ 3 - 3
tools/packages/taipy-gui/setup.requirements.txt

@@ -1,8 +1,8 @@
 charset-normalizer>=3.3.2,<=3.3.2
-flask>=3.0.0,<=3.0.3
+flask>=3.1.0,<3.2
 flask-cors>=5.0.0,<5.1
-flask-socketio>=5.3.6,<=5.3.6
-gevent>=23.7.0,<=24.2.1
+flask-socketio>=5.4.1,<5.5
+gevent>=24.11.1,<24.12
 gevent-websocket>=0.10.1,<=0.10.1
 gitignore-parser>=0.1,<=0.1.11
 kthread>=0.2.3,<=0.2.3

+ 1 - 1
tools/packages/taipy-rest/setup.requirements.txt

@@ -1,6 +1,6 @@
 apispec[yaml]>=6.3,<=6.6.1
 apispec-webframeworks>=0.5.2,<=1.1.0
-flask>=3.0.0,<=3.0.3
+flask>=3.1.0,<3.2
 flask-restful>=0.3.9,<=0.3.10
 marshmallow>=3.20.1,<=3.21.2
 passlib>=1.7.4,<=1.7.4

+ 1 - 1
tools/packages/taipy/setup.py

@@ -56,7 +56,7 @@ setup(
             "python-magic-bin>=0.4.14,<0.5;platform_system=='Windows'",
         ],
         "rdp": ["rdp>=0.8"],
-        "arrow": ["pyarrow>=17.0.0,<18.0"],
+        "arrow": ["pyarrow>=16.0.0,<19.0"],
         "mssql": ["pyodbc>=4"],
     },
     cmdclass={"build_py": NPMInstall},