diff --git a/.flake8 b/.flake8 index 06536f94d..7bb6297bf 100644 --- a/.flake8 +++ b/.flake8 @@ -1,6 +1,6 @@ [flake8] # required by black, https://github.com/psf/black/blob/master/.flake8 -max-line-length = 120 +max-line-length = 100 max-complexity = 18 ignore = E203, E266, E501, E722, W503, F403, F401 select = B,C,E,F,W,T4,B9 diff --git a/.gitignore b/.gitignore index 42b4334aa..fc0eac787 100644 --- a/.gitignore +++ b/.gitignore @@ -122,6 +122,6 @@ docs/manuals/xrefs docs/manuals/reference_rest/*.md !docs/manuals/reference_rest/index.md docs/manuals/reference_guiext/ -docs/credits/contributors.md +docs/contributing/contributors.md node_modules/ diff --git a/Pipfile b/Pipfile index aa3397ef6..95d8707f9 100644 --- a/Pipfile +++ b/Pipfile @@ -10,12 +10,11 @@ apispec-webframeworks = "==0.5.2" bcrypt = "==3.2.2" cookiecutter = "==2.1.1" deepdiff = "==6.2.2" -flask = "==2.3.3" +flask = "==3.0.0" flask-cors = "==4.0.0" -flask-jwt-extended = "==4.3" -flask-marshmallow = "==0.14" -flask-migrate = "==3.0" -flask-restful = "==0.3.9" +flask-marshmallow = ">=0.14" +flask-migrate = ">=3.0" +flask-restful = ">=0.3.9" flask-socketio = "==5.3.6" gevent = "==23.7.0" gevent-websocket = "==0.10.1" @@ -45,6 +44,8 @@ twisted = "==23.8.0" tzlocal = "==3.0" [dev-packages] +black = "*" +isort = "*" mkdocs = "*" mkdocs-autorefs = "*" mkdocs-include-markdown-plugin = "*" @@ -53,6 +54,7 @@ mkdocs-material = "*" mkdocs-material-extensions = "*" mkdocstrings = "*" mkdocstrings-python = "*" +mypy = "*" requests = "*" [requires] diff --git a/docs/contributing/code_of_conduct.md b/docs/contributing/code_of_conduct.md index 5eb8013fe..6cee35cf7 100644 --- a/docs/contributing/code_of_conduct.md +++ b/docs/contributing/code_of_conduct.md @@ -1,6 +1,4 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge +# Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body @@ -12,7 +10,7 @@ and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. -## Our Standards +# Our Standards Examples of behavior that contributes to a positive environment for our community include: @@ -36,7 +34,7 @@ Examples of unacceptable behavior include: * Other conduct which could reasonably be considered inappropriate in a professional setting. -## Enforcement Responsibilities +# Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in @@ -48,7 +46,7 @@ comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. -## Scope +# Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. @@ -56,7 +54,7 @@ Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. -## Enforcement +# Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at @@ -66,12 +64,12 @@ All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. -## Enforcement Guidelines +# Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: -### 1. Correction +## 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. @@ -80,7 +78,7 @@ unprofessional or unwelcome in the community. clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. -### 2. Warning +## 2. Warning **Community Impact**: A violation through a single incident or series of actions. @@ -92,7 +90,7 @@ includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. -### 3. Temporary Ban +## 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. @@ -103,7 +101,7 @@ private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. -### 4. Permanent Ban +## 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an @@ -112,7 +110,7 @@ individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. -## Attribution +# Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at diff --git a/docs/contributing/contributing.md b/docs/contributing/contributing.md index 6724f559e..6f7016dfd 100644 --- a/docs/contributing/contributing.md +++ b/docs/contributing/contributing.md @@ -1,66 +1,70 @@ -# Contributions +Thanks for your interest in helping improve Taipy! Contributions are welcome, and they are +greatly appreciated! Every little help and credit will always be given. -Thanks for your interest in helping improve Taipy! Contributions are welcome, and they are greatly appreciated! -Every little help and credit will always be given. - -There are multiple ways to contribute to Taipy, code, but also reporting bugs, creating feature requests, helping -other users in our forums, Stack Overflow, etc. +There are multiple ways to contribute to Taipy, code, but also reporting bugs, creating feature +requests, helping other users in our forums, Stack Overflow, etc. Several channels are open to communicate with the Taipy team: - The [taipy.io forum](https://www.taipy.io/community/) for open discussion with the Taipy team. -- [GitHub issues](https://github.com/Avaiga/taipy/issues) on the [`taipy` repository](https://github.com/Avaiga/taipy) to suggest - improvements, new features, or to report a bug. -- [GitHub discussions](https://github.com/Avaiga/taipy/discussions) on the [`taipy` repository](https://github.com/Avaiga/taipy) - for discussing technical topics related to the implementation of Taipy. -- [StackOverflow](https://stackoverflow.com/questions/tagged/taipy) for precise questions related to the usage of Taipy. +- [GitHub issues](https://github.com/Avaiga/taipy/issues) on the + [`taipy` repository](https://github.com/Avaiga/taipy) to suggest improvements, new features, + or to report a bug. +- [GitHub discussions](https://github.com/Avaiga/taipy/discussions) on the + [`taipy` repository](https://github.com/Avaiga/taipy) for discussing technical topics + related to the implementation of Taipy. +- [StackOverflow](https://stackoverflow.com/questions/tagged/taipy) for precise questions + related to the usage of Taipy. Before contributing to Taipy, please read our [Code of conduct](code_of_conduct.md). -## Never contributed to an open source project before ? +# Never contributed to an open source project before ? -Have a look at this [GitHub documentation](https://docs.github.com/en/get-started/quickstart/contributing-to-projects). +Have a look at this +[GitHub documentation](https://docs.github.com/en/get-started/quickstart/contributing-to-projects). -## Bugs report +# Bugs report Reporting bugs is through [GitHub issues](https://github.com/Avaiga/taipy/issues). -Please report relevant information and preferably code that exhibits the problem. We provide templates to help you -present the issue in a comprehensive way. +Please report relevant information and preferably code that exhibits the problem. We provide +templates to help you present the issue in a comprehensive way. -The Taipy team will analyze and try to reproduce the bug to provide feedback. If confirmed, we will add a priority -to the issue and add it in our backlog. Feel free to propose a pull request to fix it. +The Taipy team will analyze and try to reproduce the bug to provide feedback. If confirmed, we +will add a priority to the issue and add it in our backlog. Feel free to propose a pull request +to fix it. -## Issue reporting, feedback, proposal, design or any other comment +# Feedback, proposal or any comment -Any feedback or proposal is greatly appreciated! Do not hesitate to create an issue with the appropriate template on -[GitHub](https://github.com/Avaiga/taipy/issues). +Any feedback or proposal is greatly appreciated! Do not hesitate to create an issue with the +appropriate template on [GitHub](https://github.com/Avaiga/taipy/issues). The Taipy team will analyze your issue and return to you as soon as possible. -## Improve Documentation +# Improve Documentation Do not hesitate to create an issue or pull request directly on the [taipy-doc repository](https://github.com/Avaiga/taipy-doc/issues). -## Implement Features +# Implement Features -The Taipy team manages its backlog in private. Each issue that will be done during our current sprint is -attached to the `current sprint`. Please, do not work on it, the Taipy team is on it. +The Taipy team manages its backlog in private. Each issue that will be done during our current +sprint is attached to the `current sprint`. Please, do not work on it, the Taipy team is on it. -## Code organization +# Code organization -Taipy is organized in five main repositories: +Taipy is organized in several repositories: - [taipy-config](https://github.com/Avaiga/taipy-config). - [taipy-core](https://github.com/Avaiga/taipy-core). - [taipy-gui](https://github.com/Avaiga/taipy-gui). - [taipy-rest](https://github.com/Avaiga/taipy-rest). +- [taipy-templates](https://github.com/Avaiga/taipy-templates). - [taipy](https://github.com/Avaiga/taipy) brings previous packages in a single one. -## Coding style and best practices +# Best practices -### Python +## Python Taipy's repositories follow the [PEP 8](https://www.python.org/dev/peps/pep-0008/) and [PEP 484](https://www.python.org/dev/peps/pep-0484/) coding convention. @@ -70,10 +74,11 @@ Taipy's repositories follow the [PEP 8](https://www.python.org/dev/peps/pep-0008 Taipy's repositories follow the [W3Schools](https://www.w3schools.com/js/js_conventions.asp) and [Google](https://google.github.io/styleguide/tsguide.html) coding convention. -### Git branches +## Git branches All new development happens in the `develop` branch. All pull requests should target that branch. -We are following a strict branch naming convention based on the pattern: `/#[]`. +We are following a strict branch naming convention based on the pattern: +`/#[]`. Where: @@ -84,58 +89,60 @@ Where: - refactor: refactor of a piece of code. - doc: doc changes (complement or typo fixes…). - build: in relation with the build process. -- `` is the processed issue identifier. The advantage of explicitly indicating the issue number is that in - GitHub, a pull request page shows a direct link to the issue description. -- `[]` is a short summary of the issue topic, not including spaces, using Camel case or lower-case, - dash-separated words. This summary, with its dash (‘-’) symbol prefix, is optional. - +- `` is the processed issue identifier. The advantage of explicitly indicating the + issue number is that in GitHub, a pull request page shows a direct link to the issue + description. +- `[]` is a short summary of the issue topic, not including spaces, using Camel + case or lower-case, dash-separated words. This summary, with its dash (‘-’) symbol prefix, + is optional. -## Contribution workflow +# Contribution workflow -Find an issue without the label `current sprint` and add a comment on it to inform the community that you are -working on it. +Find an issue without the label `current sprint` and add a comment on it to inform the community +that you are working on it. -1. Make your [own fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) of the repository - target by the issue. Clone it on our local machine, then go inside the directory. +1. Make your [own fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) + of the repository target by the issue. Clone it on our local machine, then go inside the + directory. 2. We are working with [Pipenv](https://github.com/pypa/pipenv) for our virtual environments. - Create a local env and install development package by running `pipenv install --dev`, then run tests with - `pipenv run pytest` to verify your setup. + Create a local env and install development package by running `pipenv install --dev`, then + run tests with `pipenv run pytest` to verify your setup. 3. For convention help, we provide a [pre-commit](https://pre-commit.com/hooks.html) file. - This tool will run before each commit and will automatically reformat code or raise warnings and errors based on the - code format or Python typing. - You can install and setup it up by doing: - ``` - pipenv install pre-commit --skip-lock - pipenv run python -m pre-commit install - ``` + This tool will run before each commit and will automatically reformat code or raise warnings + and errors based on the code format or Python typing. You can install and setup it up by doing: + ```console + pipenv install pre-commit --skip-lock + pipenv run python -m pre-commit install + ``` 4. Make the change and create a - [pull request from your fork](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork). - Keep your pull request in __draft__ until your work is finished. - Do not hesitate to add a comment for help or questions. + [pull request from your fork](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork). + Keep your pull request in __draft__ until your work is finished. + Do not hesitate to add a comment for help or questions. - Before you submit a pull request read to review from your forked repo, check that it meets these guidelines: + Before you submit a pull request read to review from your forked repo, check that it meets + these guidelines: - Include tests. - Code is [rebase](http://stackoverflow.com/a/7244456/1110993). - License is present. - pre-commit works - without MyPI errors. - GitHub's actions are passing. -6. The Taipy team will have a look at your Pull Request and will give feedback. If every requirement is valid, your - work will be added in the next release, congratulation! - +5. The Taipy team will have a look at your Pull Request and will give feedback. If every + requirement is valid, your work will be added in the next release, congratulation! -## Dependency management +# Dependency management -Taipy comes with multiple optional packages. You can find the list directly in the product or Taipy's packages. -The back-end Pipfile does not install by default optional packages due to `pyodbc` requiring a driver's manual -installation. This is not the behavior for the front-end that installs all optional packages through its Pipfile. +Taipy comes with multiple optional packages. You can find the list directly in the product or +Taipy's packages. The back-end Pipfile does not install by default optional packages due to +`pyodbc` requiring a driver's manual installation. This is not the behavior for the front-end +that installs all optional packages through its Pipfile. -If you are a contributor on Taipy, be careful with dependencies, do not forget to install or uninstall depending on -your issue. +If you are a contributor on Taipy, be careful with dependencies, do not forget to install or +uninstall depending on your issue. -If you need to add to Taipy a new dependency, do not forget to add it in the `Pipfile` and `setup.py`. -Keep in mind that dependency is a vector of attack. The Taipy team limits the usage of external dependencies at the -minimum. +If you need to add to Taipy a new dependency, do not forget to add it in the `Pipfile` and +`setup.py`. Keep in mind that dependency is a vector of attack. The Taipy team limits the usage +of external dependencies at the minimum. diff --git a/docs/credits/contributors.md_template b/docs/contributing/contributors.md_template similarity index 100% rename from docs/credits/contributors.md_template rename to docs/contributing/contributors.md_template diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md index 4a198dac2..dd55c95fc 100644 --- a/docs/getting_started/index.md +++ b/docs/getting_started/index.md @@ -1,14 +1,16 @@ --- +title: Getting Started with Taipy hide: - navigation --- -# Getting Started with Taipy - -Dive into Taipy with this beginner-friendly guide. Learn to install, configure, and deploy your +Dive into Taipy with this beginner-friendly guide. Learn to install, configure, and create your first application with ease. -## Installation with pip +![GUI Result](result.png){width=50% style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } + + +# Installation with pip 1. **Prerequisites**: Ensure you have Python (version 3.8 or higher) and [pip](https://pip.pypa.io)installed. @@ -18,12 +20,12 @@ first application with ease. $ pip install taipy ``` -!!! info "Other installation options" +??? info "Other installation options" For alternative installation methods or if you're lacking Python or pip, refer to the [installation page](../installation/index.md). -## Your First Taipy Scenario +# Your First Taipy Scenario A Taipy *Scenario* models pipeline executions. Think of it as an execution graph where tasks or functions collaborate and exchange data. You have full control over how complex your scenario @@ -109,7 +111,7 @@ The graph involves: Hello Taipy! ``` -## Build a graphical interface +# Build a graphical interface While we've used Taipy's Python APIs to handle our scenario, it usually works seamlessly with a graphical interface, also created using Taipy, to provide a more user-friendly experience. @@ -180,7 +182,7 @@ In our initial example: - *message* is connected to a text field, allowing you to display changing content to the user. -### Interactivity Through Actions +## Interactivity Through Actions Actions, like `on_action=submit_scenario`, allow visual elements like buttons to trigger specific functions, enhancing the interactivity of the application. diff --git a/docs/installation/index.md b/docs/installation/index.md index 2e62a0d15..60cd1c0d6 100644 --- a/docs/installation/index.md +++ b/docs/installation/index.md @@ -1,14 +1,14 @@ --- +title: Install Taipy hide: - navigation --- -# Install Taipy Welcome to the installation section of the Taipy web application builder! This section will guide you through the seamless and straightforward process of setting up and deploying your own powerful web applications. -## Prerequisite +# Prerequisite Before installing Taipy, ensure you have Python (version 3.8 or above) and [pip](https://pip.pypa.io) installed on your system. If you don't have pip installed, you can @@ -33,7 +33,7 @@ $ conda install pip To install Taipy, you have several options depending on your needs and preferences. -## Installing Taipy - Stable release +# Installing Taipy - Stable release The preferred method to install Taipy is by using **pip**. Open your terminal or command prompt and run the following command: @@ -44,7 +44,7 @@ $ pip install taipy This command will download and install the most recent stable release of Taipy. -## Installing Taipy in a Conda Environment +# Installing Taipy in a Conda Environment Conda is an open-source package management system and environment management system that runs on Windows, macOS, and Linux. @@ -65,7 +65,7 @@ environment, follow these steps: $ pip install taipy ``` -## Installing Taipy from Source +# Installing Taipy from Source If you want to work with the latest development version or contribute to the project, you can install Taipy from the source code. diff --git a/docs/knowledge_base/demos/bar_cutting.md b/docs/knowledge_base/demos/bar_cutting.md index 0c6ef3769..bbfc68900 100644 --- a/docs/knowledge_base/demos/bar_cutting.md +++ b/docs/knowledge_base/demos/bar_cutting.md @@ -3,7 +3,7 @@ to minimize waste. Bar-cutting optimization minimizes waste by choosing optimal cutting patterns. This is crucial in industries with significant material costs such as Steel, Timber, etc. -[Try it Live](https://bar-cutting.taipy.cloud/Databases) +[Try it live](https://bar-cutting.taipy.cloud/Databases){: .tp-btn target='blank' } # Understand the Application The application comprises five pages accessible via the left panel. diff --git a/docs/knowledge_base/demos/churn_classification.md b/docs/knowledge_base/demos/churn_classification.md index 21356eead..17cdd5fbe 100644 --- a/docs/knowledge_base/demos/churn_classification.md +++ b/docs/knowledge_base/demos/churn_classification.md @@ -4,11 +4,8 @@ more cost-effective than acquiring new ones. By identifying customers who may leave early and applying retention strategies, businesses can lower churn rates and boost customer loyalty. - - -[Try it live](https://churn-classification.taipy.cloud/Data-Visualization) - -[Get it on GitHub](https://github.com/Avaiga/demo-churn-classification) +[Try it live](https://churn-classification.taipy.cloud/Data-Visualization){: .tp-btn target='blank' } +[Get it on GitHub](https://github.com/Avaiga/demo-churn-classification){: .tp-btn .tp-btn--accent target='blank' } # Understanding the Application The application comprises four pages accessible via the left panel. diff --git a/docs/knowledge_base/demos/covid_dashboard.md b/docs/knowledge_base/demos/covid_dashboard.md index b7c74df13..81b058fb2 100644 --- a/docs/knowledge_base/demos/covid_dashboard.md +++ b/docs/knowledge_base/demos/covid_dashboard.md @@ -3,13 +3,11 @@ Pages show different graphs and information on Covid. A Prediction page is also present to predict the number of casualties. -[Try it live](https://covid-dashboard.taipy.cloud/Country) - -[Get it on GitHub](https://github.com/Avaiga/demo-covid-dashboard) +[Try it live](https://covid-dashboard.taipy.cloud/Country){: .tp-btn target='blank' } +[Get it on GitHub](https://github.com/Avaiga/demo-covid-dashboard){: .tp-btn .tp-btn--accent target='blank' } # Understanding the Application -The application comprises four pages accessible via the upper tabs: Country, Map, Predictions, -World. +The application comprises four pages accessible via the upper tabs: Country, Map, Predictions, World. ## Page 1: Country - Country-specific COVID-19 statistics. diff --git a/docs/knowledge_base/demos/face_recognition.md b/docs/knowledge_base/demos/face_recognition.md index 3bcec40ea..d4e88aec8 100644 --- a/docs/knowledge_base/demos/face_recognition.md +++ b/docs/knowledge_base/demos/face_recognition.md @@ -3,9 +3,8 @@ offering a user-friendly real-time face detection experience using your webcam.Just as a reminder, face recognition technology enables computers to identify human faces in images and videos. -[Try it live](https://face-recognition.taipy.cloud/) - -[Get it on GitHub](https://github.com/Avaiga/demo-face-recognition) +[Try it live](https://face-recognition.taipy.cloud/){: .tp-btn target='blank' } +[Get it on GitHub](https://github.com/Avaiga/demo-face-recognition){: .tp-btn .tp-btn--accent target='blank' } # Understanding the Application diff --git a/docs/knowledge_base/demos/image_classif.md b/docs/knowledge_base/demos/image_classif.md index bd91144ba..b44ff6576 100644 --- a/docs/knowledge_base/demos/image_classif.md +++ b/docs/knowledge_base/demos/image_classif.md @@ -2,7 +2,7 @@ Through these two videos, we take you on a journey to create interactive image classification applications using Taipy, [Nvidia CUDA](https://developer.nvidia.com/cuda-toolkit) , and [TensorFlow](https://www.tensorflow.org/). -[Get it on GitHub](https://github.com/Avaiga/demo-image-classification-part-1) +[Get it on GitHub](https://github.com/Avaiga/demo-image-classification-part-1){: .tp-btn .tp-btn--accent target='blank' } # Video 1: [Building an Interactive Image Classification Application with Taipy and Nvidia CUDA](https://youtu.be/WWBmd-yG4B8?si=mnpkGpiMEfJT6EMD) diff --git a/docs/knowledge_base/demos/images/icon-code.svg b/docs/knowledge_base/demos/images/icon-code.svg new file mode 100644 index 000000000..118b9c23b --- /dev/null +++ b/docs/knowledge_base/demos/images/icon-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/knowledge_base/demos/images/icon-video.svg b/docs/knowledge_base/demos/images/icon-video.svg new file mode 100644 index 000000000..6cf3a6f70 --- /dev/null +++ b/docs/knowledge_base/demos/images/icon-video.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/knowledge_base/demos/index.md b/docs/knowledge_base/demos/index.md index 7fb4febb8..a7541086b 100644 --- a/docs/knowledge_base/demos/index.md +++ b/docs/knowledge_base/demos/index.md @@ -1,16 +1,199 @@ +--- +hide: + - toc +--- + Let's explore demos of applications made with Taipy. -# Demos -| Id | Title | description | keywords | -|:----|:---------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------:| -| 1 | [Sentiment Analysis with Taipy: Unlock Insights from Text](sentiment_analysis.md) | Explore the power of Taipy's sentiment analysis capabilities with our two-page application. Analyze user input and uploaded text to uncover sentiments effortlessly. | Sentiment Analysis with Taipy | -| 2 | [Real-time Face Recognition with Taipy: A Powerful Demo](face_recognition.md) | Explore real-time face detection and recognition with Taipy's intuitive GUI component. Learn how to create custom UI components and utilize OpenCV for accurate face identification. | Face Recognition with Taipy | -| 3 | [Exploring Movie Genres with Taipy: A Genre Selector Demo](movie_genre_selector.md) | Dive into the world of movies and genres with Taipy's Genre Selector demo. Learn how to use this intuitive tool to discover your favorite movie genres effortlessly. | Movie Genre Selector with Taipy | -| 4 | [Create Unique Tweets with Taipy: Tweet Generation Demo](tweet_generation.md) | Discover the magic of AI-powered Tweet Generation with Taipy's innovative platform. Craft engaging Tweets effortlessly using GPT-3's Davinci engine for text and DALL·E for images. | AI-Powered Tweet Generation | -| 5 | [Data Visualization Made Easy with Taipy: Sales Dashboard Demo](sales_dashboard.md) | Explore the power of Taipy's Sales Dashboard demo, a tool that reads Excel files and displays insightful results. Filter data by city, customer, and gender to uncover specific metrics and utilize two dynamic charts for trend analysis. | Sales Dashboard with Taipy | -| 6 | [Interactive Image Classification with Taipy, Nvidia CUDA, and TensorFlow](image_classif.md) | Dive into our video tutorial series and learn how to create interactive image classification applications using Taipy, Nvidia CUDA, and TensorFlow. Explore the power of Taipy for ML workflows and get ready for part 2 on data pipelines. | Interactive Image Classification with Taipy, Nvidia CUDA, and TensorFlow | -| 7 | [Building a Comprehensive COVID-19 Dashboard with Taipy](covid_dashboard.md) | Explore the capabilities of Taipy as we showcase the creation of a minimalist yet powerful COVID-19 dashboard. Visualize and predict COVID-19 data for different countries, explore interactive maps, and gain insights into the global impact of the pandemic. | COVID-19 Data Visualization, Pandemic Dashboard | -| 8 | [Empowering Financial Insights: Stock Visualization with Taipy and Prophet](stock_visualization.md)| Explore the Stock Visualization demo, a stock data dashboard that leverages Taipy GUI and Prophet to visualize historical stock data and make predictions for the next 1 to 5 years. Discover the power of Taipy in simplifying data visualization for financial insights.| Stock Visualization with Taipy and Prophet | -| 9 | [Predictive Power Unleashed: Churn Classification with Taipy](churn_classification.md) | Dive into the Churn Classification demo, a powerful application that leverages Taipy for exploratory data analysis, model management, and comparing predictive models. Discover the potential of Taipy in streamlining churn prediction and enhancing decision-making. | Churn Classification with Taipy | -| 10 | [Streamlining Production Planning with Taipy: The Ultimate Solution](production_planning.md) | Explore the Production Planning demo, a powerful application that leverages Taipy's capabilities to optimize production levels, minimize costs, and simulate scenarios for a manufacturing process. Discover how Taipy simplifies complex production planning. | Production Planning with Taipy | -| 11 | [Precision Cutting Unleashed: Bar Cutting Optimization with Taipy](bar_cutting.md) | Explore the Bar Cutting demo, a powerful application that leverages Taipy to optimize bar cutting for two cases using different algorithms. Discover how Taipy streamlines the cutting process and minimizes losses in a visually intuitive manner. | Bar Cutting Optimization with Taipy | + +
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
+ + diff --git a/docs/knowledge_base/demos/movie_genre_selector.md b/docs/knowledge_base/demos/movie_genre_selector.md index 58d3fccf4..00e25b3d8 100644 --- a/docs/knowledge_base/demos/movie_genre_selector.md +++ b/docs/knowledge_base/demos/movie_genre_selector.md @@ -1,6 +1,6 @@ -[Try it live](https://demo-movie-genre.taipy.cloud/) -[Get it on GitHub](https://github.com/Avaiga/demo-movie-genre) +[Try it live](https://demo-movie-genre.taipy.cloud/){: .tp-btn target='blank' } +[Get it on GitHub](https://github.com/Avaiga/demo-movie-genre){: .tp-btn .tp-btn--accent target='blank' } # Understanding the Application This demo illustrates Taipy's capability to analyze CSV files diff --git a/docs/knowledge_base/demos/production_planning.md b/docs/knowledge_base/demos/production_planning.md index 313670585..81fa2f566 100644 --- a/docs/knowledge_base/demos/production_planning.md +++ b/docs/knowledge_base/demos/production_planning.md @@ -1,9 +1,8 @@ Production planning is pivotal in manufacturing, optimizing resources to meet demand while minimizing costs. This demo offers a solution for efficient production and cost management. -[Try it live](https://production-planning.taipy.cloud/Data-Visualization) - -[Get it on GitHub](https://github.com/Avaiga/demo-production-planning) +[Try it live](https://production-planning.taipy.cloud/Data-Visualization){: .tp-btn target='blank' } +[Get it on GitHub](https://github.com/Avaiga/demo-production-planning){: .tp-btn .tp-btn--accent target='blank' } # Understanding the Application The application consists of five pages accessible via the left panel by expanding the menu list. diff --git a/docs/knowledge_base/demos/sales_dashboard.md b/docs/knowledge_base/demos/sales_dashboard.md index 4efb3b01f..63586f915 100644 --- a/docs/knowledge_base/demos/sales_dashboard.md +++ b/docs/knowledge_base/demos/sales_dashboard.md @@ -2,11 +2,8 @@ This demo allows users to extract data from an Excel file and derive meaningful When Users apply filters based on city, customer type, and gender, Taipy automatically refreshes the two charts: "_Sales by hour_" and "_Sales by product_". - -[Try it live](https://sales-dashboard.taipy.cloud/) - -[Get it on GitHub](https://github.com/Avaiga/demo-sales-dashboard) - +[Try it live](https://sales-dashboard.taipy.cloud/){: .tp-btn target='blank' } +[Get it on GitHub](https://github.com/Avaiga/demo-sales-dashboard){: .tp-btn .tp-btn--accent target='blank' } # Understanding the Application This demo is a one-page application. diff --git a/docs/knowledge_base/demos/sentiment_analysis.md b/docs/knowledge_base/demos/sentiment_analysis.md index 8c6b9176a..749248669 100644 --- a/docs/knowledge_base/demos/sentiment_analysis.md +++ b/docs/knowledge_base/demos/sentiment_analysis.md @@ -4,10 +4,8 @@ It helps businesses and individuals better grasp the feelings, and tones expressed in written content. Taipy's sentiment analysis application excels in making this process highly efficient and accurate. - -[Try it live](https://sentiment-analysis.taipy.cloud/line) - -[Get it on GitHub](https://github.com/Avaiga/demo-sentiment-analysis) +[Try it live](https://sentiment-analysis.taipy.cloud/line){: .tp-btn target='blank' } +[Get it on GitHub](https://github.com/Avaiga/demo-sentiment-analysis){: .tp-btn .tp-btn--accent target='blank' } # Understanding the Application The application comprises two pages accessible via the upper tabs: "_Line_", "_Text_" diff --git a/docs/knowledge_base/demos/stock_visualization.md b/docs/knowledge_base/demos/stock_visualization.md index 757810f50..7e3a4adec 100644 --- a/docs/knowledge_base/demos/stock_visualization.md +++ b/docs/knowledge_base/demos/stock_visualization.md @@ -5,10 +5,8 @@ This demo, built with Taipy and powered by the [Prophet library](https://facebook.github.io/prophet/docs/quick_start.html), offers a way to achieve this. -## [Try it live](https://stock-visualization.taipy.cloud/) - -## [Get it on GitHub](https://github.com/Avaiga/demo-stock-visualization) - +[Try it live](https://stock-visualization.taipy.cloud/){: .tp-btn target='blank' } +[Get it on GitHub](https://github.com/Avaiga/demo-stock-visualization){: .tp-btn .tp-btn--accent target='blank' } # Understanding the Application This one-page demo's primary objective is to illustrate how diff --git a/docs/knowledge_base/demos/tweet_generation.md b/docs/knowledge_base/demos/tweet_generation.md index 19f6943d2..7e5525255 100644 --- a/docs/knowledge_base/demos/tweet_generation.md +++ b/docs/knowledge_base/demos/tweet_generation.md @@ -5,10 +5,8 @@ for image generation. This application should be useful for individuals and businesses seeking to improve their social media presence. - -[Try it live](https://tweet-generation.taipy.cloud/) - -[Get it on GitHub](https://github.com/Avaiga/demo-tweet-generation) +[Try it live](https://tweet-generation.taipy.cloud/){: .tp-btn target='blank' } +[Get it on GitHub](https://github.com/Avaiga/demo-tweet-generation){: .tp-btn .tp-btn--accent target='blank' } # Understanding the Application This application highlights several key features: diff --git a/docs/knowledge_base/hidden.md b/docs/knowledge_base/hidden.md deleted file mode 100644 index 5aa820592..000000000 --- a/docs/knowledge_base/hidden.md +++ /dev/null @@ -1,42 +0,0 @@ - -| Id | Title | keywords | -|:----|:----------------------------------------------------------------------------------------|:--------------------------------------------------------| -| 1 | [Understanding GUI](tutorials/understanding_gui/index.md) | Application front-end building | -| 2 | [Scenario management Overview](tutorials/scenario_management_overview/index.md) | Dataflow orchestration | -| 3 | [First Realistic application](tutorials/complete_application/index.md) | Complete Taipy Application | -| 4 | [Create a single-page web application with Taipy](tutorials/markdown_syntax.md) | Creating a Single Web Application | -| 5 | [Create a Data Dashboard without HTML, CSS and Java Script](tutorials/data_dashboard.md)| Creating a Data Dashboard | -| 6 | [Change line types using charts](tutorials/charts.md) | Taipy Line Types With Charts | -| 7 | [Organize your application](tutorials/graphical_pages.md) | Organize Your Application | -| 8 | [Organize your applications with Partials, Dialogs, Panes](tutorials/partials.md) | Organizing Taipy applications, Partials, Dialogs, Panes | -| 9 | [Taipy dataflow orchestration basic concepts](tutorials/scenario_mgt_concepts.md) | Dataflow orchestration basic concepts | -| 10 | [How to execute your dataflow orchestration](tutorials/execution.md) | Execute Your Dataflow orchestration | - -# Demos -| Id | Title | description | keywords | -|:----|:---------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------:| -| 1 | [Sentiment Analysis with Taipy: Unlock Insights from Text](demos/sentiment_analysis.md) | Explore the power of Taipy's sentiment analysis capabilities with our two-page application. Analyze user input and uploaded text to uncover sentiments effortlessly. | Sentiment Analysis with Taipy | -| 2 | [Real-time Face Recognition with Taipy: A Powerful Demo](demos/face_recognition.md) | Explore real-time face detection and recognition with Taipy's intuitive GUI component. Learn how to create custom UI components and utilize OpenCV for accurate face identification. | Face Recognition with Taipy | -| 3 | [Exploring Movie Genres with Taipy: A Genre Selector Demo](demos/movie_genre_selector.md) | Dive into the world of movies and genres with Taipy's Genre Selector demo. Learn how to use this intuitive tool to discover your favorite movie genres effortlessly. | Movie Genre Selector with Taipy | -| 4 | [Create Unique Tweets with Taipy: Tweet Generation Demo](demos/tweet_generation.md) | Discover the magic of AI-powered Tweet Generation with Taipy's innovative platform. Craft engaging Tweets effortlessly using GPT-3's Davinci engine for text and DALL·E for images. | AI-Powered Tweet Generation | -| 5 | [Data Visualization Made Easy with Taipy: Sales Dashboard Demo](demos/sales_dashboard.md) | Explore the power of Taipy's Sales Dashboard demo, a tool that reads Excel files and displays insightful results. Filter data by city, customer, and gender to uncover specific metrics and utilize two dynamic charts for trend analysis. | Sales Dashboard with Taipy | -| 6 | [Interactive Image Classification with Taipy, Nvidia CUDA, and TensorFlow](demos/image_classif.md) | Dive into our video tutorial series and learn how to create interactive image classification applications using Taipy, Nvidia CUDA, and TensorFlow. Explore the power of Taipy for ML workflows and get ready for part 2 on data pipelines. | Interactive Image Classification with Taipy, Nvidia CUDA, and TensorFlow | -| 7 | [Building a Comprehensive COVID-19 Dashboard with Taipy](demos/covid_dashboard.md) | Explore the capabilities of Taipy as we showcase the creation of a minimalist yet powerful COVID-19 dashboard. Visualize and predict COVID-19 data for different countries, explore interactive maps, and gain insights into the global impact of the pandemic. | COVID-19 Data Visualization, Pandemic Dashboard | -| 8 | [Empowering Financial Insights: Stock Visualization with Taipy and Prophet](demos/stock_visualization.md)| Explore the Stock Visualization demo, a stock data dashboard that leverages Taipy GUI and Prophet to visualize historical stock data and make predictions for the next 1 to 5 years. Discover the power of Taipy in simplifying data visualization for financial insights. | Stock Visualization with Taipy and Prophet | -| 9 | [Predictive Power Unleashed: Churn Classification with Taipy](demos/churn_classification.md) | Dive into the Churn Classification demo, a powerful application that leverages Taipy for exploratory data analysis, model management, and comparing predictive models. Discover the potential of Taipy in streamlining churn prediction and enhancing decision-making. | Churn Classification with Taipy | -| 10 | [Streamlining Production Planning with Taipy: The Ultimate Solution](demos/production_planning.md) | Explore the Production Planning demo, a powerful application that leverages Taipy's capabilities to optimize production levels, minimize costs, and simulate scenarios for a manufacturing process. Discover how Taipy simplifies complex production planning. | Production Planning with Taipy | -| 11 | [Optimizing Bar Cut Sizes with Taipy](demos/bar_cutting.md) | Explore the Bar Cut Optimization demo, a powerful application that leverages Taipy to optimize bar cutting for two cases using different algorithms. Discover how Taipy streamlines the cutting process and minimizes losses in a visually intuitive manner. | Bar Cutting Optimization with Taipy | - -# Tips and tricks -| Id | Title | description | keywords | md page link | -|:----|:------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------:|------------------------------------------------------------------------------------------------------------------------------:| -| 13 | Scenarios | A Taipy scenario represents a run that can be an instance of a business problem to solve on data and parameter sets. | Taipy Scenarios | [The Scenarios](https://www.taipy.io/tips/the-scenarios/) | -| 14 | Sharing a Taipy Application on Colab with Ngrok | Learn how to deploy your Taipy Application on Colab (Google Colab offers a high-performance Notebook environment with CPU and GPU access for Deep Learning), using a tunnel to the internet through a public URL created with Ngrok. | Taipy Application on Colab | [Sharing a Taipy Application on Colab with Ngrok](https://www.taipy.io/tips/sharing-a-taipy-application-on-colab-with-ngrok/) | -| 15 | [Taipy front-end in Jupyter Notebooks](tips/jupyter_notebooks/index.md) | Discover how to streamline your coding experience with Taipy in Jupyter Notebooks. Learn essential functions for seamless front-end updates without the need to restart the kernel. Optimize your Python scripts for efficiency today! | Taipy in Jupyter Notebooks | [Taipy GUI in Jupyter Notebooks](https://www.taipy.io/tips/taipy-gui/taipy-gui-in-jupyter-notebooks/) | -| 16 | Long-running Callbacks | Explore how Taipy's 'long-running callbacks' revolutionize web applications by ensuring server-client communication remains responsive during time-consuming tasks. Learn through practical examples in this article and unlock the potential of enhanced user experiences with Taipy. | Long-running Callbacks | [Long running Callbacks](https://www.taipy.io/tips/long-running-callbacks/) | -| 17 | Multi-page application | Say goodbye to cluttered dashboards! Discover the power of multi-page applications with Taipy. Organize your data and visualizations effortlessly, creating user-friendly and intuitive dashboards for enhanced insights. Simplify your data visualization journey today! | Multi-page application | [Multi-page application](https://www.taipy.io/tips/multipage-application/) | -| 18 | Learn about using tables | Discover the power of Taipy front-end tables – your go-to for data presentation and control. Learn key settings and features in this article, tailored for effortless table creation within data applications. Simplify your data management with Taipy today! | Tables | [Learn about Using tables](https://www.taipy.io/tips/using-tables/) | -| 19 | The data nodes | Explore the world of data nodes in Taipy pipelines. Learn about their crucial role and how they seamlessly access data from diverse sources. This article is your gateway to understanding data nodes in Taipy! | Data nodes | [The data nodes](https://www.taipy.io/tips/the-data-nodes/) | -| 20 | The CSS Style Kit | Elevate your Taipy applications with the all-new CSS Style Kit! Transform aesthetics effortlessly with predefined stylesheets, CSS variables, and utility classes. Discover how to customize your app's look and feel for a visually stunning experience. | CSS Style Kit | [The CSS Style Kit](https://www.taipy.io/tips/the-css-style-kit/) | -| 21 | The skippable tasks | Discover the power of 'skippable' tasks in Taipy's back-end. Learn how to leverage this key feature for dynamically orchestrating tasks in your data processing pipelines. Explore the efficiency of Taipy's approach to task management today! | Skippable Tasks | [The skippable tasks](https://www.taipy.io/tips/the-skippable-tasks/) | -| 22 | The on-change callback | Explore the power of on-change callbacks in Taipy for the GUI. Learn how these Python functions drive user interactions, from adjusting sliders to input actions, and discover their pivotal role in building a wide range of web applications. Dive into the world of web application development with Taipy! | on-change callback | [The "on_change" callback](https://www.taipy.io/tips/the-on_change-callback/) | diff --git a/docs/knowledge_base/images/icon-demos.svg b/docs/knowledge_base/images/icon-demos.svg new file mode 100644 index 000000000..844de59c3 --- /dev/null +++ b/docs/knowledge_base/images/icon-demos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/knowledge_base/images/icon-tips.svg b/docs/knowledge_base/images/icon-tips.svg new file mode 100644 index 000000000..cf2c85c2e --- /dev/null +++ b/docs/knowledge_base/images/icon-tips.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/knowledge_base/images/icon-tutorials.svg b/docs/knowledge_base/images/icon-tutorials.svg new file mode 100644 index 000000000..4e178c49c --- /dev/null +++ b/docs/knowledge_base/images/icon-tutorials.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/knowledge_base/index.md b/docs/knowledge_base/index.md index 3660b756a..217bcc138 100644 --- a/docs/knowledge_base/index.md +++ b/docs/knowledge_base/index.md @@ -1,46 +1,582 @@ -Learn how to use Taipy and improve your skills with the following tutorials. +--- +hide: + - toc +--- + +Learn how to use Taipy and improve your skills. + + + + +
+ + +
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
# Tutorials -| Id | Title | description | keywords | -|:----|:-----------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------| -| 1 | [Understanding GUI](tutorials/understanding_gui/index.md) | Gain a fundamental understanding of creating a multi-page NLP application using Taipy front-end. | Application front-end building | -| 2 | [Scenario management Overview](tutorials/scenario_management_overview/index.md) | Learn the main features of the Taipy scenario management | Dataflow orchestration | -| 3 | [First Realistic application](tutorials/complete_application/index.md) | Build a complete application from scratch from back-end to front-end | Complete Taipy Application | -| 4 | [Create a single-page web application with Taipy](tutorials/markdown_syntax.md) | Master the art of web application development with Taipy! Watch and learn as we demonstrate creating a basic application page using augmented Markdown syntax with Taipy. Explore variable bindings and discover how to incorporate visual elements such as sliders and charts. | Creating a Single Web Application | -| 5 | [Create a Data Dashboard without HTML, CSS and Java Script](tutorials/data_dashboard.md) | Explore advanced visual elements in Taipy through this video as we guide you through creating a dynamic data dashboard. Learn how to upload datasets, fine-tune parameters, and unleash the power of diverse graphical options for data visualization. Elevate your web application skills with Taipy without the need of HTML, CSS and JS!" | Creating a Data Dashboard | -| 6 | [Change line types using charts](tutorials/charts.md) | Discover the simplicity of crafting line charts for your Taipy application in this instructional video. Walk you through the process using a basic time series dataset with two variables. | Taipy Line Types With Charts | -| 7 | [Organize your application](tutorials/XXX.md) | Learn the art of organizing and managing multiple graphical pages in this insightful video tutorial. Unlock the potential for creating a personalized and user-friendly interface with Taipy. | Organize Your Application | -| 8 | [Organize your applications with Partials, Dialogs, Panes](tutorials/partials.md) | Explore the power of Partials in Taipy front-end with this video tutorial. Learn how to streamline development, enhance clarity, and create efficient GUI pages and components. Discover the utility of Dialogs and Panes for an improved user interface. | Organizing Taipy applications, Partials, Dialogs, Panes | -| 9 | [GS with Taipy Dataflow Orchestration (to merge with #2?)](tutorials/XXX.md) | Learn the essentials of building multi-scenario pipeline-driven applications with Taipy entities in this informative video tutorial. Explore data nodes, tasks, pipelines, and scenarios as they collaborate in managing complex data-driven applications. Dive into a hands-on demo using a diamond dataset, where machine learning models predict prices based on feature subsets. Create and manage multiple scenarios effortlessly with Taipy! | Get Started with Dataflow Orchestration | -| 10 | [Taipy dataflow orchestration basic concepts](tutorials/XXX.md) | Discover Taipy's back-end for effortless dataflow orchestration, data pipeline creation, and management. Explore Taipy main concepts: Data Node, Task, Pipeline, and Scenario through the Taipy graphical editor interface: Taipy Studio, in this enlightening video tutorial. Revolutionize your data workflow with Taipy today! | Dataflow orchestration basic concepts | -| 11 | [How to execute your dataflow orchestration](tutorials/XXX.md) | Join us for part two of our exploration into Taipy back-end, for streamlined dataflow creation and management. Dive into a real-world use case, where we demonstrate the step-by-step process of harnessing your data's potential with Taipy back-end key components: Data nodes and Tasks. Unleash the power of efficient data pipelines today! | Execute Your Dataflow orchestration | -| 12 | [Taipy smart task skipping](tutorials/XXX.md) | Explore Taipy intelligent task-skipping feature for enhanced dataflow and pipeline efficiency in this video tutorial. Don't miss out on both parts of this informative video series! | Smart Task Skipping | - + + + # Demos -| Id | Title | description | keywords | -|:----|:---------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------:| -| 1 | [Sentiment Analysis with Taipy: Unlock Insights from Text](demos/sentiment_analysis.md) | Explore the power of Taipy's sentiment analysis capabilities with our two-page application. Analyze user input and uploaded text to uncover sentiments effortlessly. | Sentiment Analysis with Taipy | -| 2 | [Real-time Face Recognition with Taipy: A Powerful Demo](demos/face_recognition.md) | Explore real-time face detection and recognition with Taipy's intuitive GUI component. Learn how to create custom UI components and utilize OpenCV for accurate face identification. | Face Recognition with Taipy | -| 3 | [Exploring Movie Genres with Taipy: A Genre Selector Demo](demos/movie_genre_selector.md) | Dive into the world of movies and genres with Taipy's Genre Selector demo. Learn how to use this intuitive tool to discover your favorite movie genres effortlessly. | Movie Genre Selector with Taipy | -| 4 | [Create Unique Tweets with Taipy: Tweet Generation Demo](demos/tweet_generation.md) | Discover the magic of AI-powered Tweet Generation with Taipy's innovative platform. Craft engaging Tweets effortlessly using GPT-3's Davinci engine for text and DALL·E for images. | AI-Powered Tweet Generation | -| 5 | [Data Visualization Made Easy with Taipy: Sales Dashboard Demo](demos/sales_dashboard.md) | Explore the power of Taipy's Sales Dashboard demo, a tool that reads Excel files and displays insightful results. Filter data by city, customer, and gender to uncover specific metrics and utilize two dynamic charts for trend analysis. | Sales Dashboard with Taipy | -| 6 | [Interactive Image Classification with Taipy, Nvidia CUDA, and TensorFlow](demos/image_classif.md) | Dive into our video tutorial series and learn how to create interactive image classification applications using Taipy, Nvidia CUDA, and TensorFlow. Explore the power of Taipy for ML workflows and get ready for part 2 on data pipelines. | Interactive Image Classification with Taipy, Nvidia CUDA, and TensorFlow | -| 7 | [Building a Comprehensive COVID-19 Dashboard with Taipy](demos/covid_dashboard.md) | Explore the capabilities of Taipy as we showcase the creation of a minimalist yet powerful COVID-19 dashboard. Visualize and predict COVID-19 data for different countries, explore interactive maps, and gain insights into the global impact of the pandemic. | COVID-19 Data Visualization, Pandemic Dashboard | -| 8 | [Empowering Financial Insights: Stock Visualization with Taipy and Prophet](demos/stock_visualization.md)| Explore the Stock Visualization demo, a stock data dashboard that leverages Taipy GUI and Prophet to visualize historical stock data and make predictions for the next 1 to 5 years. Discover the power of Taipy in simplifying data visualization for financial insights. | Stock Visualization with Taipy and Prophet | -| 9 | [Predictive Power Unleashed: Churn Classification with Taipy](demos/churn_classification.md) | Dive into the Churn Classification demo, a powerful application that leverages Taipy for exploratory data analysis, model management, and comparing predictive models. Discover the potential of Taipy in streamlining churn prediction and enhancing decision-making. | Churn Classification with Taipy | -| 10 | [Streamlining Production Planning with Taipy: The Ultimate Solution](demos/production_planning.md) | Explore the Production Planning demo, a powerful application that leverages Taipy's capabilities to optimize production levels, minimize costs, and simulate scenarios for a manufacturing process. Discover how Taipy simplifies complex production planning. | Production Planning with Taipy | -| 11 | [Optimizing Bar Cut Sizes with Taipy](demos/bar_cutting.md) | Explore the Bar Cut Optimization demo, a powerful application that leverages Taipy to optimize bar cutting for two cases using different algorithms. Discover how Taipy streamlines the cutting process and minimizes losses in a visually intuitive manner. | Bar Cutting Optimization with Taipy | - -# Tips and tricks -| Id | Title | description | keywords | md page link | -|:----|:------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------:|------------------------------------------------------------------------------------------------------------------------------:| -| 13 | Scenarios | A Taipy scenario represents a run that can be an instance of a business problem to solve on data and parameter sets. | Taipy Scenarios | [The Scenarios](https://www.taipy.io/tips/the-scenarios/) | -| 14 | Sharing a Taipy Application on Colab with Ngrok | Learn how to deploy your Taipy Application on Colab (Google Colab offers a high-performance Notebook environment with CPU and GPU access for Deep Learning), using a tunnel to the internet through a public URL created with Ngrok. | Taipy Application on Colab | [Sharing a Taipy Application on Colab with Ngrok](https://www.taipy.io/tips/sharing-a-taipy-application-on-colab-with-ngrok/) | -| 15 | [Taipy front-end in Jupyter Notebooks](tips/jupyter_notebooks/index.md) | Discover how to streamline your coding experience with Taipy in Jupyter Notebooks. Learn essential functions for seamless front-end updates without the need to restart the kernel. Optimize your Python scripts for efficiency today! | Taipy in Jupyter Notebooks | [Taipy GUI in Jupyter Notebooks](https://www.taipy.io/tips/taipy-gui/taipy-gui-in-jupyter-notebooks/) | -| 16 | Long-running Callbacks | Explore how Taipy's 'long-running callbacks' revolutionize web applications by ensuring server-client communication remains responsive during time-consuming tasks. Learn through practical examples in this article and unlock the potential of enhanced user experiences with Taipy. | Long-running Callbacks | [Long running Callbacks](https://www.taipy.io/tips/long-running-callbacks/) | -| 17 | Multi-page application | Say goodbye to cluttered dashboards! Discover the power of multipage applications with Taipy. Organize your data and visualizations effortlessly, creating user-friendly and intuitive dashboards for enhanced insights. Simplify your data visualization journey today! | Multi-page application | [Multi-page application](https://www.taipy.io/tips/multipage-application/) | -| 18 | Learn about using tables | Discover the power of Taipy front-end tables – your go-to for data presentation and control. Learn key settings and features in this article, tailored for effortless table creation within data applications. Simplify your data management with Taipy today! | Tables | [Learn about Using tables](https://www.taipy.io/tips/using-tables/) | -| 19 | The data nodes | Explore the world of data nodes in Taipy pipelines. Learn about their crucial role and how they seamlessly access data from diverse sources. This article is your gateway to understanding data nodes in Taipy! | Data nodes | [The data nodes](https://www.taipy.io/tips/the-data-nodes/) | -| 20 | The CSS Style Kit | Elevate your Taipy applications with the all-new CSS Style Kit! Transform aesthetics effortlessly with predefined stylesheets, CSS variables, and utility classes. Discover how to customize your app's look and feel for a visually stunning experience. | CSS Style Kit | [The CSS Style Kit](https://www.taipy.io/tips/the-css-style-kit/) | -| 21 | The skippable tasks | Discover the power of 'skippable' tasks in Taipy's back-end. Learn how to leverage this key feature for dynamically orchestrating tasks in your data processing pipelines. Explore the efficiency of Taipy's approach to task management today! | Skippable Tasks | [The skippable tasks](https://www.taipy.io/tips/the-skippable-tasks/) | -| 22 | The on-change callback | Explore the power of on-change callbacks in Taipy for the GUI. Learn how these Python functions drive user interactions, from adjusting sliders to input actions, and discover their pivotal role in building a wide range of web applications. Dive into the world of web application development with Taipy! | on-change callback | [The "on_change" callback](https://www.taipy.io/tips/the-on_change-callback/) | + + +# Tips & Tricks + + \ No newline at end of file diff --git a/docs/knowledge_base/tips/images/icon-code.svg b/docs/knowledge_base/tips/images/icon-code.svg new file mode 100644 index 000000000..e1bb33f7c --- /dev/null +++ b/docs/knowledge_base/tips/images/icon-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/knowledge_base/tips/images/icon-video.svg b/docs/knowledge_base/tips/images/icon-video.svg new file mode 100644 index 000000000..70910014f --- /dev/null +++ b/docs/knowledge_base/tips/images/icon-video.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/knowledge_base/tips/index.md b/docs/knowledge_base/tips/index.md index 324e8be0a..9621522e4 100644 --- a/docs/knowledge_base/tips/index.md +++ b/docs/knowledge_base/tips/index.md @@ -1 +1,211 @@ +--- +hide: + - toc +--- + Tips and Tricks! + + +
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
+ + \ No newline at end of file diff --git a/docs/knowledge_base/tips/multipage_application/index.md b/docs/knowledge_base/tips/multipage_application/index.md new file mode 100644 index 000000000..9ed9411ef --- /dev/null +++ b/docs/knowledge_base/tips/multipage_application/index.md @@ -0,0 +1,306 @@ + +Are you tired of messy and confusing dashboards that make it hard to find the information you +need? If so, it might be a good idea to switch to multi-page applications! + +![Multi-page Application](multipage_application.png){width=100%} + +Multi-page applications allow you to organize your data and visualizations into separate pages, +making it easier to navigate and focus on specific insights. At Taipy, we understand how +important clear and effective data visualization is, which is why we've created a multi-page +feature that lets you build user-friendly dashboards that are easy to understand. + +We've prepared a two-part series of articles to explain how to use Taipy's multi-page functionality: + +In Part 1, we'll go over the basics of creating a multi-page application, including how to set +up your application and add pages. + +Stay tuned for Part 2, where we'll cover more advanced features like interactivity and +customization. Taipy makes creating multi-page applications a breeze. + +So, if you're ready to enhance your data visualization, check out our multi-page feature and +start creating your own intuitive and insightful applications with Taipy. + +# Part 1 – Building a Multi-Page Application + +While it's possible to create a multi-page Taipy application in a single script, it's often a +good practice to organize your code into a folder structure like this: + +```console +app/ +├─ main.py +├─ pages/ +│ ├─ home.py +│ ├─ temperature.py +``` + +In this arrangement, every submodule in the **pages** folder (like `home.py` and `temperature.py`) +holds the code for each page in our application. We're demonstrating with just two pages in this +example, but you can add as many as you need. + +## Defining the Pages + +To make it simple, we'll ensure that each page does not affect any other page. In other words, +when you do something on one page, it won't affect the other pages. We'll discuss how pages +interact with each other in the second part of this series. + +Now, let's examine the code for each of our page modules. + +```python title="home.py" +from taipy.gui import Markdown + +text = "Welcome to the Taipy multi-page tutorial app!" + +home_md = Markdown(""" +# Home + +<|{text}|> +""") +``` + +```python title="temperature.py" +from taipy.gui import Markdown + +def fahrenheit_to_celsius(fahrenheit): + return (fahrenheit - 32) * 5 / 9 + +fahrenheit = 100 +celsius = fahrenheit_to_celsius(fahrenheit) + +temperature_md = Markdown(""" +# Fahrenheit to Celsius + +Farenheit: <|{fahrenheit}|> +Celsius: <|{celsius}|> +""") +``` + +No need to worry if you don't understand all the code details! What's important is that both +pages work independently: + +- The `home_md` page shows a welcome message. +- The `temperature_md` page lets a user convert temperatures from Fahrenheit (°F) to Celsius (°C). + +Usually, if we were making a simple one-page application, we'd give one of our pages (Taipy +[Markdown](../../../manuals/reference/taipy.gui.Markdown.md) or +[HTML](../../../manuals/reference/taipy.gui.Html.md) objects) to the +`[`Gui` constructor](Gui.init()^)` constructor. For example, to turn `home.py` into a one-page +Taipy application, +we could add these lines: + +```python title="home.py, as a standalone one-page app" +from taipy.gui import Markdown, Gui + +# same code as before + +home_md = Markdown(…) # same content as before + +Gui(page=home_md).run() # or simply, Gui(home_md).run() +``` + +## Running the Multi-Page Application + +Up to this point, we've structured our multi-page Taipy application by keeping two one-page +applications in a sub-folder named `pages`. + +Now, the next step is to create and define our main module, `main.py` within the `app/` folder. +After that, we'll initialize our multi-page Gui object. + +```python title="main.py" +from taipy.gui import Gui +from pages.home import home_md +from pages.temperature import temperature_md + +pages = {"home": home_md, "temperature": temperature_md} + +Gui(pages=pages).run() +``` + +We started by importing two Markdown objects, `home_md` and `temperature_md` from the two +scripts we previously created. Then, we made a dictionary called `pages`: + +1. Each key in the dictionary specifies the URL where you can access that page. +2. Each value in the dictionary is the `Markdown^` object for that page. + +In the end, we provided this *pages* dictionary as an argument to the *pages* parameter of the +`Gui` object. Then, we called its `run()` method, and that's how we got our first Taipy +multi-page application working! + +If you open your web browser and go to **localhost:5000** (assuming you're using the +[default port](../../../manuals/reference/taipy.gui.Gui.md)), you'll see the following: + +![Defining a Multi-Page Application](multipage_application_7.png){width=50%} + +You're directed to the */home* URL automatically because it was the first page listed in the +`pages` dictionary, and that's where you'll find our first page! + +If you change the URL from */home* to */temperature*, you will see the following: + +![Defining a Multi-Page Application](multipage_application_8.png){width=50%} + +## Navigating between pages + +Manually changing the URL to navigate between pages isn't ideal. Taipy provides several methods +for adding navigation to your multi-page application, making it more user-friendly and intuitive. + +### 1. The navbar + +![The navbar](multipage_application_9.gif){width=50%} + +One straightforward technique to make your application's navigation more appealing is by utilizing +the Taipy [`navbar`](../../../manuals/gui/viselements/navbar.md) control. To incorporate the +navbar into the home page, all you need to do is add a single line to the beginning of the +*home_md* page definition: + +```python title="home.py, with navbar" +from taipy.gui import Markdown + +text = "Welcome to the converter app!" + +home_md = Markdown(""" +<|navbar|> + +# Home + +<|{text}|> +""") +``` + +By default, the navbar control automatically creates an entry for each page in the `pages` +dictionary, requiring no further required specification of properties - making it a quick and +easy way to add navigation. + +However, the code change above only added a navbar to the *home_md* page - we would still need to +make the same change to *temperature_md* and any other page we have in our application. A better +alternative that does not require any code modification in any of the pages is to add a +**root page**. + +Rather than modifying each page to include the navbar, we can also simply modify `main.py` to +utilize the [root page](../../../manuals/gui/pages/index.md#root-page): + +```python title="main.py, with root page navbar" +from taipy.gui import Gui +from pages.home import home_md +from pages.temperature import temperature_md + +pages = { + "/": "<|navbar|>", + "home": home_md, + "temperature": temperature_md, +} + +Gui(pages=pages).run() +``` + +Since every page inherits the root page, you can easily make every page inherit the navbar control +by adding just one line to `main.py`.
+ +As an additional tip, you can use HTML *center* tags to center the `navbar` on the page: +`
<|navbar|>
` + +The concept of the *root* page is more advanced in Taipy and will be explored in more detail in +Part 2 of this Taipy multi-page series. + +### 2. The navigate function + +The `navigate()^` function is self-explanatory in its purpose, it is used to navigate to +other pages. For example, this is a code snippet of the `navigate()^` function being used to +navigate to the *home* page when the [button](../../../manuals/gui/viselements/button.md) +control is clicked: + +```python +from taipy.gui import navigate + +md = "<|Click to go Home|button|on_action=go_home|>" +def go_home(state): + navigate(state, "home") +``` + +Naturally, this function is only used within callbacks. To use `navigate()^`, we simply pass along +the *state* variable present in all callbacks, as well as the name of the page we wish to go to. +In the example above, the user will be directed to the */home* page. + +The `navigate()^` function provides a lot of flexibility to the developer to manage navigation +in the application beyond what the navbar offers. For example, we can manage: + +1. After executing some process, direct the user to either the /success or /failure page + depending on the process status. + +2. Direct the user back to the /home page when an exception occurs + by using navigate in [on_exception](../../../manuals/gui/callbacks.md#exception-handling). + +If you prefer, you can replicate the functionality of the *navbar* using the `navigate()^` feature +with a different control, like a [selector](../../../manuals/gui/viselements/selector.md) +control or [tree](../../../manuals/gui/viselements/tree.md) control. In this example, let's +combine the `navigate` feature with the [menu](../../../manuals/gui/viselements/menu.md) control +(a collapsible side panel) to create the following app: + +![The navigate function](multipage_application_11.gif){width=50%} + +The menu navigation was implemented by modifying `main.py` to the following: + +```python title="main.py, with menu navigation" +from taipy.gui import Gui, navigate +from pages.home import home_md +from pages.temperature import temperature_md + +pages = { + "/": "<|menu|lov={page_names}|on_action=menu_action|>", + "home": home_md, + "temperature": temperature_md, +} +page_names = [page for page in pages.keys() if page != "/"] + +def menu_action(state, id, action, payload): + page = payload["args"][0] + navigate(state, page) + +gui = Gui(pages=pages) +gui.run(run_browser=False, use_reloader=True) +``` + +Unlike `navbar` which automatically populates its *lov* (list of values) with the page names +and intrinsically navigates the user to the selected page when it is interacted with, the code +example above using the menu control and navigate is a little more verbose. + +We define two properties for the menu control: + +1. `lov={page_names}`: The list of values which may be selected from the menu. + In this case, we interpolate the *page_names* variable, which we then assign the keys from + *pages* (other than "/") — functionally equivalent to `page_names = ["home", "temperature"]`. + Refer to the [menu](../../../manuals/gui/viselements/menu.md) for more details, such as for + setting icons and labels. +2. `on_action=menu_action`: Assigns the `menu_action` function as the callback function which is + executed when the user clicks an item from the menu. + +We define the *menu_action()* function with the parameters as stated in the menu control +documentation, then call `navigate(state, page)^` to direct the user to the selected *page*. In +practice, we effectively have the same functionality as the navbar, but had to do a bit more +work to expressly create that functionality. + +### 3. Hyperlinks + +Finally, the simplest way to implement navigation in Taipy is with a hyperlink: + +```python title="main.py, with hyperlink to temperature page" +from taipy.gui import Markdown + +home_md = Markdown(""" +# Home + +Go to [temperature](/temperature) page. +""") +``` + +This results in the following clickable "/temperature" text, which directs the user to the +*/temperature* URL: + +![Hyperlinks](multipage_application_14.png){width=50%} + +# Part 2 - Advanced Multi-Page Applications + +In preparation for Part 2 of the **Taipy Tips: Building a Multi-Page Application** series, you +can anticipate learning about the following topics: + +1. Accessing state variables across multiple pages, enabling interaction between pages. +2. Gaining insight into how Taipy GUI searches for variables and functions utilized in pages. +3. Practical code examples to illustrate these concepts. diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application.png b/docs/knowledge_base/tips/multipage_application/multipage_application.png new file mode 100644 index 000000000..25eac587c Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_10.png b/docs/knowledge_base/tips/multipage_application/multipage_application_10.png new file mode 100644 index 000000000..99755f779 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_10.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_11.gif b/docs/knowledge_base/tips/multipage_application/multipage_application_11.gif new file mode 100644 index 000000000..5c25642ef Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_11.gif differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_11.png b/docs/knowledge_base/tips/multipage_application/multipage_application_11.png new file mode 100644 index 000000000..744776d41 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_11.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_12.png b/docs/knowledge_base/tips/multipage_application/multipage_application_12.png new file mode 100644 index 000000000..60f488f70 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_12.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_13.png b/docs/knowledge_base/tips/multipage_application/multipage_application_13.png new file mode 100644 index 000000000..47af773c1 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_13.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_14.png b/docs/knowledge_base/tips/multipage_application/multipage_application_14.png new file mode 100644 index 000000000..784a2cb02 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_14.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_2.png b/docs/knowledge_base/tips/multipage_application/multipage_application_2.png new file mode 100644 index 000000000..a590c04a1 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_2.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_3.png b/docs/knowledge_base/tips/multipage_application/multipage_application_3.png new file mode 100644 index 000000000..5124b8242 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_3.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_4.png b/docs/knowledge_base/tips/multipage_application/multipage_application_4.png new file mode 100644 index 000000000..73a80ad5b Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_4.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_5.png b/docs/knowledge_base/tips/multipage_application/multipage_application_5.png new file mode 100644 index 000000000..26e81112d Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_5.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_6.png b/docs/knowledge_base/tips/multipage_application/multipage_application_6.png new file mode 100644 index 000000000..44a2293f7 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_6.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_7.png b/docs/knowledge_base/tips/multipage_application/multipage_application_7.png new file mode 100644 index 000000000..19dd376de Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_7.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_8.png b/docs/knowledge_base/tips/multipage_application/multipage_application_8.png new file mode 100644 index 000000000..cd687fe87 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_8.png differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_9.gif b/docs/knowledge_base/tips/multipage_application/multipage_application_9.gif new file mode 100644 index 000000000..804e68268 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_9.gif differ diff --git a/docs/knowledge_base/tips/multipage_application/multipage_application_9.png b/docs/knowledge_base/tips/multipage_application/multipage_application_9.png new file mode 100644 index 000000000..515aebe46 Binary files /dev/null and b/docs/knowledge_base/tips/multipage_application/multipage_application_9.png differ diff --git a/docs/knowledge_base/tips/multithreading/index.md b/docs/knowledge_base/tips/multithreading/index.md new file mode 100644 index 000000000..caec3d943 --- /dev/null +++ b/docs/knowledge_base/tips/multithreading/index.md @@ -0,0 +1,121 @@ +Taipy can display data that is generated in a separate thread. This is useful for displaying +real-time data from a sensor or a simulator. For example displaying in a dashboard the +information from sensors measuring air pollution around a city, or displaying CPU usage of +a server. + +

+ Dashboard Example +

+ +In this article, we will code a simple example where: +- A `sender.py` script will generate a random number and send it through a socket. +- A `receiver.py` script will receive and display the number in a Taipy application. + +

+ VSCode Screenshot +

+ +## Step 1: Create the Sender Script + +Here is the code for the `sender.py` script: + +```python title="sender.py" +import time +import socket + +from random import randint + +HOST = "127.0.0.1" +PORT = 5050 + +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((HOST, PORT)) + while True: + random_number = randint(1, 100) + s.sendall(str(random_number).encode()) + print(f"Sending: {random_number}") + time.sleep(5) +``` + +This script generates a random number between 1 and 100, sends it through a socket, and waits +5 seconds before sending another number. + +## Step 2: Create the Receiver Script + +Coding the receiver script requires multiple steps: + +1. Imports and defining the socket parameters. + +```python title="receiver.py" +import socket +from threading import Thread +from taipy.gui import Gui, State, invoke_callback, get_state_id + +HOST = "127.0.0.1" +PORT = 5050 +``` + +2. We gather the list of state identifiers. These are identifiers of the clients connected to +our Taipy application. We need this list to choose which client to send the data to. + +```python title="receiver.py" +state_id_list = [] + +def on_init(state: State): + state_id = get_state_id(state) + if (state_id := get_state_id(state)) is not None: + state_id_list.append(state_id) +``` + +3. We create a function to listen to the socket. When the socket receives data, it triggers a +callback to send the data to the Taipy application for one of the connected clients. + +```python title="receiver.py" +def client_handler(gui: Gui, state_id_list: list): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind((HOST, PORT)) + s.listen() + conn, _ = s.accept() + while True: + if data := conn.recv(1024): + print(f"Data received: {data.decode()}") + if hasattr(gui, "_server") and state_id_list: + invoke_callback( + gui, state_id_list[0], update_received_data, (int(data.decode()),) + ) + else: + print("Connection closed") + break + + +def update_received_data(state: State, val): + state.received_data = val +``` + +4. We create the Taipy application to display the data. The *client_handler()* function and +the application itself are run in different threads. + +```python title="receiver.py" +received_data = 0 + +md = """ +Received Data: <|{received_data}|> +""" +gui = Gui(page=md) + +t = Thread( + target=client_handler, + args=( + gui, + state_id_list, + ), +) +t.start() + +gui.run(title="Receiver Page") +``` + +## Step 3: Run the Scripts + +Run the `receiver.py` script first, then the `sender.py` script in another terminal. The +receiver will receive and display the sender's data in the Taipy application. \ No newline at end of file diff --git a/docs/knowledge_base/tips/multithreading/realtime_dashboard.png b/docs/knowledge_base/tips/multithreading/realtime_dashboard.png new file mode 100644 index 000000000..e44fef271 Binary files /dev/null and b/docs/knowledge_base/tips/multithreading/realtime_dashboard.png differ diff --git a/docs/knowledge_base/tips/multithreading/vscode_screen.png b/docs/knowledge_base/tips/multithreading/vscode_screen.png new file mode 100644 index 000000000..7b260c837 Binary files /dev/null and b/docs/knowledge_base/tips/multithreading/vscode_screen.png differ diff --git a/docs/knowledge_base/tips/skippable_tasks/index.md b/docs/knowledge_base/tips/skippable_tasks/index.md index e9dc0fa66..5a050cb2a 100644 --- a/docs/knowledge_base/tips/skippable_tasks/index.md +++ b/docs/knowledge_base/tips/skippable_tasks/index.md @@ -25,7 +25,7 @@ It contains: Before you start using skippable tasks, it's important to configure your tasks correctly with their Data nodes. You can refer to our previous article or -documentation for more details on [Data nodes](../../../tips/the_data_nodes/). +documentation for more details on [Data nodes](../../tips/the_data_nodes/index.md). For instance, let's say you have a function like *multiply_and_add()* that takes two parameters and returns two values. How can you represent this function as a Taipy Task? diff --git a/docs/knowledge_base/tips/taipy_cloud_deploy/index.md b/docs/knowledge_base/tips/taipy_cloud_deploy/index.md index 92177a734..68b251ec2 100644 --- a/docs/knowledge_base/tips/taipy_cloud_deploy/index.md +++ b/docs/knowledge_base/tips/taipy_cloud_deploy/index.md @@ -3,7 +3,7 @@ Welcome to Taipy Cloud, the platform designed to make application deployment eas ensuring accessibility and stability. In this detailed guide, we will take you through the process of deploying a Taipy application on Taipy Cloud. -![Taipy Cloud](taipy_cloud.png){width=100%} +![Taipy Cloud](logo_artwork.png){width=100%} We'll cover everything from configuration to testing. diff --git a/docs/knowledge_base/tips/taipy_cloud_deploy/logo_artwork.png b/docs/knowledge_base/tips/taipy_cloud_deploy/logo_artwork.png new file mode 100644 index 000000000..b6e2863bb Binary files /dev/null and b/docs/knowledge_base/tips/taipy_cloud_deploy/logo_artwork.png differ diff --git a/docs/knowledge_base/tips/the_data_nodes/index.md b/docs/knowledge_base/tips/the_data_nodes/index.md index 7a815c072..6f3791d19 100644 --- a/docs/knowledge_base/tips/the_data_nodes/index.md +++ b/docs/knowledge_base/tips/the_data_nodes/index.md @@ -35,7 +35,8 @@ It can handle various types of Python stuff like strings, numbers, lists, dictio models (for machine learning or other things), and data tables. Here's some code that uses two Pickle data nodes: one for getting data in and one for sending data out. -- *model* is an input *Pickle* data node. It looks at a Pickle file called *model.p* and gets data from there. +- *model* is an input *Pickle* data node. It looks at a Pickle file called *model.p* and gets + data from there. - *predictions* is an output data node, but right now, it doesn't have any data in it. We haven't told it where to get data from yet. @@ -45,7 +46,8 @@ two Pickle data nodes: one for getting data in and one for sending data out. Your browser does not support the video tag. -Once you've set up this basic graph, the next step is to create a scenario using it and then submit it for execution. +Once you've set up this basic graph, the next step is to create a scenario using it and then +submit it for execution. ```python scenario = tp.create_scenario(scenario_cfg) @@ -57,8 +59,8 @@ When submitting the scenario (for execution), Taipy: - executes the *predict()* function, - and writes the results in a Pickle file. -Taipy makes things easy by handling the paths for Pickle files automatically if you haven't defined them. -This simplifies the configuration process. When you create several scenarios, +Taipy makes things easy by handling the paths for Pickle files automatically if you haven't +defined them. This simplifies the configuration process. When you create several scenarios, the output data nodes from each scenario will automatically point to separate Pickle files. ```py @@ -92,10 +94,10 @@ These data nodes allow you to work with tabular data from different sources with To use Tabular data nodes in Taipy, you only need to include them in the configuration -and specify certain parameters, like a default path for CSV or Parquet files. -It's important to note that you can change this path during runtime. -For instance, if you create a new scenario, you can instruct the Tabular data nodes -to save the results in a different file or directory, which helps you avoid overwriting previous data. +and specify certain parameters, like a default path for CSV or Parquet files. It's important to +note that you can change this path during runtime. For instance, if you create a new scenario, +you can instruct the Tabular data nodes to save the results in a different file or directory, +which helps you avoid overwriting previous data. ```py scenario = tp.create_scenario(scenario_cfg) @@ -107,10 +109,11 @@ When you submit the scenario described above for execution in Taipy, the followi - Taipy reads the CSV file named `data.csv` because it is the input data node. - It takes the data from the CSV file and passes it to the *some_preprocessing()* function - using the chosen exposed type, which is typically a Pandas DataFrame by default. + using the chosen exposed type, which is typically a Pandas DataFrame by default. - After the processing is done, Taipy writes or overwrites the result, - which is typically in the form of a Pandas DataFrame, into the Parquet file located at *data.parquet*. + which is typically in the form of a Pandas DataFrame, into the Parquet file located at + *data.parquet*. - This Parquet file may overwrite any existing data in that file if it already exists. @@ -124,21 +127,21 @@ to other types, such as *Numpy arrays*: ## Generic Data Nodes -The **Generic** data node in Taipy is a flexible option that users can customize -to include their own *read()* and *write()* functions. This feature is particularly useful -when dealing with data sources that don't have a predefined Taipy Data node. -With a Generic data node, you can tailor it to access data in specific formats or from custom sources. +The **Generic** data node in Taipy is a flexible option that users can customize to include +their own *read()* and *write()* functions. This feature is particularly useful when dealing +with data sources that don't have a predefined Taipy Data node. With a Generic data node, you +can tailor it to access data in specific formats or from custom sources. -For more detailed information and guidance on using the Generic data node -and customizing it to your specific needs, I recommend checking the -[Taipy documentation](../../../manuals/core/config/data-node-config/#generic), +For more detailed information and guidance on using the Generic data node and customizing it to +your specific needs, I recommend checking the +[Taipy documentation](../../../manuals/core/config/data-node-config.md#generic), which will provide you with step-by-step instructions and examples. -Taipy integrates two other predefined storage types to work with documents. -Check the documentation for more details. +Taipy integrates two other predefined storage types to work with documents. Check the +documentation for more details. -- [Mongo](../../../manuals/core/config/data-node-config/#mongo-collection) -- [Json](../../../manuals/core/config/data-node-config/#json) +- [Mongo](../../../manuals/core/config/data-node-config.md#mongo-collection) +- [Json](../../../manuals/core/config/data-node-config.md#json) ## Conclusion diff --git a/docs/knowledge_base/tips/the_on_change_callback/callbacks_demo.gif b/docs/knowledge_base/tips/the_on_change_callback/callbacks_demo.gif new file mode 100644 index 000000000..c9dc0f1bf Binary files /dev/null and b/docs/knowledge_base/tips/the_on_change_callback/callbacks_demo.gif differ diff --git a/docs/knowledge_base/tips/the_on_change_callback/callbacks_demo_fahrenheit_to_celsius.gif b/docs/knowledge_base/tips/the_on_change_callback/callbacks_demo_fahrenheit_to_celsius.gif new file mode 100644 index 000000000..c9dc0f1bf Binary files /dev/null and b/docs/knowledge_base/tips/the_on_change_callback/callbacks_demo_fahrenheit_to_celsius.gif differ diff --git a/docs/knowledge_base/tips/the_on_change_callback/callbacks_demo_fahrenheit_to_celsius_cropped-1.gif b/docs/knowledge_base/tips/the_on_change_callback/callbacks_demo_fahrenheit_to_celsius_cropped-1.gif new file mode 100644 index 000000000..ddc083fd0 Binary files /dev/null and b/docs/knowledge_base/tips/the_on_change_callback/callbacks_demo_fahrenheit_to_celsius_cropped-1.gif differ diff --git a/docs/knowledge_base/tips/the_on_change_callback/callbacks_flowchart-1.png b/docs/knowledge_base/tips/the_on_change_callback/callbacks_flowchart-1.png new file mode 100644 index 000000000..d635deedf Binary files /dev/null and b/docs/knowledge_base/tips/the_on_change_callback/callbacks_flowchart-1.png differ diff --git a/docs/knowledge_base/tips/the_on_change_callback/index.md b/docs/knowledge_base/tips/the_on_change_callback/index.md new file mode 100644 index 000000000..34484dc3c --- /dev/null +++ b/docs/knowledge_base/tips/the_on_change_callback/index.md @@ -0,0 +1,217 @@ + +In Taipy, an on_change callback is a Python function which is executed when some application +variable is modified. This callback is used for implementing some behavior after the user +performs an action, such as dragging a slider to define the value of some parameter or typing +some text into an input box. + +![Callback](callbacks_demo.gif){width=50%} + +Note that Taipy supports various types of callbacks which serve different purposes +although this tip focuses on just one. + +These callbacks are: + +- *on_change*, the topic of this tip +- *on_action* +- *on_init* +- *on_navigate* +- *on_exception* + +When referring to callbacks in this article, we are referring to *on_change callbacks only*, +and these alone are sufficient to build simple to complex web-apps! + +That being said, let’s go through the two variations of *on_change* callbacks: + +- Local (or control-bound) *on_change* callbacks; and +- Global *on_change* callbacks + +# Example 1: Fahrenheit to Celsius (Local Callback) + +Local callbacks are functions that are bound to a specific +[Taipy control](../../../manuals/gui/controls.md) (a type of visual element). +This function then gets called when the user interacts with that control. +For instance, in Taipy, this may happen when a user: + +1. Drags a [slider](../../../manuals/gui/viselements/slider.md) control to select some number; +2. Selects a date using the [date](../../../manuals/gui/viselements/date.md) control; or +3. Selects an item from the [selector](../../../manuals/gui/viselements/selector.md) control + +![Example 1](callbacks_demo_fahrenheit_to_celsius_cropped-1.gif){width=50%} + +Let’s demonstrate local callbacks with a small example. +This simple app allows a user to select a temperature in degrees Fahrenheit +and automatically convert it to degrees Celsius: + +```python linenums="1" +from taipy.gui import Gui, Markdown + +def fahrenheit_to_celsius(fahrenheit): + return (fahrenheit - 32) * 5 / 9 + +fahrenheit = 100 +celsius = fahrenheit_to_celsius(fahrenheit) + +md = Markdown(""" +# Local Callbacks +## Fahrenheit: +<|{fahrenheit}|number|on_change=update_celsius|> + +## Celsius: +<|{celsius}|number|active=False|> +""") + +def update_celsius(state): + state.celsius = fahrenheit_to_celsius(state.fahrenheit) + +Gui(page=md).run() +``` + +The relevant line here is line 12, where we defined a number control using the Taipy construct +syntax. We will use this to select the temperature in degrees Fahrenheit which we wish to be +automatically converted to degrees Celsius. + +The aforementioned construct consists of 3 components (bordered by the pipes): + +- *{fahrenheit}*: The variable attached to this number control; +- *number*: The name of the Taipy control; and +- *on_change=update_celsius*: Sets this control’s on_change local callback to the update_celsius + function + +The update_celsius local callback function defined on line 18 receives one parameter, which we +conventionally name state. + +We can use this state object within our function to access and modify the runtime variables +used in our application, which we also call state variables. Accordingly, we update celsius on +line 19. + +Now, when the user interacts with the number control, the update_celsius local callback computes +and updates the state variable of celsius, displaying its new value. + +# Example 2: Celsius to Kelvin (Global Callback) + +The next improvement to our app is yet another simple one: add a new number control to display +the temperature in kelvin. + +![Example 2](callbacks_demo_fahrenheit_to_celsius.gif){width=50%} + +Take a look at the updated code: + +```python linenums="1" +from taipy.gui import Gui, Markdown + +def fahrenheit_to_celsius(fahrenheit): + return (fahrenheit - 32) * 5 / 9 + +def celsius_to_kelvin(celsius): + return celsius + 273.15 + +fahrenheit = 100 +celsius = fahrenheit_to_celsius(fahrenheit) +kelvin = celsius_to_kelvin(celsius) + +md = Markdown(""" +# Local and Global Callbacks +## Fahrenheit: +<|{fahrenheit}|number|on_change=update_celsius|> + +## Celsius: +<|{celsius}|number|active=False|> + +## Kelvin: +<|{kelvin}|number|active=False|> +""") + +def update_celsius(state): + state.celsius = fahrenheit_to_celsius(state.fahrenheit) + +def on_change(state, var_name, var_value): + if var_name == "celsius": + state.kelvin = celsius_to_kelvin(state.celsius) + +Gui(page=md).run(dark_mode=False) +``` + +On line 22, we added a new number control to our app, which is bound to the kelvin variable. The +existing code we implemented in the previous section — which updates celsius when fahrenheit is +modified — is maintained. + +Now the behavior we wish to implement here is to update the value of kelvin whenever the value +of celsius is modified. + +This is a perfect use case for the global on_change callback function. Take a look at this handy +flowchart which determines the type of on_change function that would be called: + +![Example 2](callbacks_flowchart-1.png){width=100%} + +This flowchart visualizes the process in which Taipy determines which *on_change* function would +be called. + +In this example, our update_celsius function executed the code: + +```python +state.celsius = fahrenheit_to_celsius(state.fahrenheit) +``` + +We call this programmatically modifying the celsius variable. Looking at the flowchart above, we +know that the global on_change function would be called, if it exists. + +The global callback function should have the exact name *on_change* so that Taipy automatically +recognizes it. The parameters for the global on_change function are conventionally named as follows: + +1. *state*: The State object with which we can access and modify our runtime variables; +2. *var_name*: The name of the variable that was modified; and +3. *var_value*: The value of the variable that was modified + +Notice that on line 33, we preceded our updates to kelvin with an if `var_name == "celsius"` +block. Within the on_change function, we almost always want to operate within an if block, to +avoid unintentionally infinitely recursion through *on_change*. Remember that programmatically +modifying kelvin or any other variables will also call the *on_change* function, though that +execution would make no changes because of our if block. + +You might also have noticed that the functionality in this section could also have been +accomplished by updating kelvin using the existing update_celsius local callback — and indeed, +adding a global callback was not necessary for this particular situation. However, you may +encounter some situations where you may not be able to use local callbacks alone, so using the +global callback may be the right choice. + +# Example 3: No Callbacks + +Side-tracking a little from the focus of this article, it’s worth noting that this app never +actually needed callbacks! We can update the code as follows: + +```python +from taipy.gui import Gui, Markdown + +def fahrenheit_to_celsius(fahrenheit): + return (fahrenheit - 32) * 5 / 9 + +def celsius_to_kelvin(celsius): + return celsius + 273.15 + +fahrenheit = 100 +celsius = fahrenheit_to_celsius(fahrenheit) +kelvin = celsius_to_kelvin(celsius) + +md = Markdown(""" +# Global Callbacks +## Fahrenheit: +<|{fahrenheit}|number|> + +## Celsius: +<|{fahrenheit_to_celsius(fahrenheit)}|number|active=False|> + +## Kelvin: +<|{celsius_to_kelvin(fahrenheit_to_celsius(fahrenheit))}|number|active=False|> +""") + +Gui(page=md).run() +``` + +Without using any callbacks, we instead simply interpolate the expression to be evaluated into +the curly braces for both the celsius and kelvin controls — much like an f-string! Since the +fahrenheit state variable is present in the expression, Taipy knows that the expression should +be reevaluated whenever fahrenheit is modified. + +A drawback of this approach however is that the function fahrenheit_to_celsius is executed twice. +For a function as simple as this one, this drawback is insignificant. However, if this was a +heavy and uncacheable function, we would certainly want to avoid executing it unnecessarily. diff --git a/docs/knowledge_base/tips/the_on_change_callback/sine_wave_value-2.gif b/docs/knowledge_base/tips/the_on_change_callback/sine_wave_value-2.gif new file mode 100644 index 000000000..fb25b2709 Binary files /dev/null and b/docs/knowledge_base/tips/the_on_change_callback/sine_wave_value-2.gif differ diff --git a/docs/knowledge_base/tips/using_tables/index.md b/docs/knowledge_base/tips/using_tables/index.md new file mode 100644 index 000000000..20a406f76 --- /dev/null +++ b/docs/knowledge_base/tips/using_tables/index.md @@ -0,0 +1,323 @@ + +Tables in Taipy are not just for showing data, they also let you control things. When you're +making an application with data (which Taipy is great at!), you can use Taipy's tables and their +cool features. + +![Tables in Taipy](using_tables.png){width=100%} + +This article shows you the settings most people want when they make tables. If you want to do +something with tables that's not in this article, you can check the +[table control](../../../manuals/gui/viselements/table.md) documentation for a big list of stuff! + +You can see all the code with the table features we talked about at the end of this article. + +![Tables in Taipy](tables-full-demo-1.gif){width=100%} + +First, let's see how you make tables in Taipy: + +```python title="main.py" +from taipy.gui import Gui, Markdown +import pandas as pd + +food_df = pd.DataFrame({ + "Meal": ["Lunch", "Dinner", "Lunch", "Lunch", "Breakfast", "Breakfast", "Lunch", "Dinner"], + "Category": ["Food", "Food", "Drink", "Food", "Food", "Drink", "Dessert", "Dessert"], + "Name": ["Burger", "Pizza", "Soda", "Salad", "Pasta", "Water", "Ice Cream", "Cake"], + "Calories": [300, 400, 150, 200, 500, 0, 400, 500], +}) + +main_md = Markdown("<|{food_df}|table|>") + +Gui(page=main_md).run() +``` + +The table definition `<|{food_df}|table|>` (a syntax often used in Taipy) has these parts: + +1. `{food_df}`: This is a variable that holds data, like what someone ate in a day. +2. `table`: This is control type name. + +In this example, the data in *food_df* is a **pandas DataFrame**. If it works better for what +you're doing, you can also use regular Python lists or NumPy arrays. + +When you run the code above, you get a page that looks like this: + +![Tables in Taipy](using_tables_2.png){width=70%} + +To add aggregation to our table, we need to specify the column to group, and the aggregation +function to be performed. In our food tracker example, an application could be to: + +1. Group by *Category*; and +2. Sum the *Calories*. + +```python +main_md = Markdown("<|{food_df}|table|group_by[Category]=True|apply[Calories]=sum|>") +``` +To configure table aggregation, you add two properties to the table: + +1. `group_by[Category]=True`: This tells the table to group data by the **Category** column. + You can use this property multiple times with different column names. + +2. `apply[Calories]=sum`: This specifies that the **Calories**' column should be combined + using the `sum` function. You can choose from various aggregation functions + like `first` (default), `last`, `count`, `sum`, `mean`, `median`, `min`, `max`, and `std`.
+ You can even use a custom function if needed. + +Note that the **Meal** and **Name** columns don't have a specific aggregation function assigned, +so they default to `first`. + +As a side note, if it's more suitable for your needs, you can create a separate table to display +the aggregated data. To do this, you can make a new DataFrame (e.g., *df_agg*) from *df* with +the desired changes, connect it to a new table, and update the new DataFrame when *df* changes. +However, this topic is about showing toggleable aggregation by dynamically updating the same table. + +## Filtering Data + +We can add filters to our table. + +![Filtering Data](tables-filter.gif){width=100%} + +Filters help us choose specific data by using one or more columns. For instance, we can pick +only the values above 300 in the **Calories** column or just view **Breakfast** in the **Meal** +column. + +To add filters to our table, it's easy: we set the `filter` property to True, like this: + +```python +main_md = Markdown("<|{food_df}|table|filter=True|>") +``` + +As with all control Boolean properties, we can remove the '=True' part, making it: +`<|{food_df}|table|filter|>`. + +## Styling (Stylekit) + +You can customize the style of a table in Taipy using two properties: + +1. *class_name*: This property allows you to apply a CSS class to the entire table. + +2. *style*: With this property, you can apply a CSS class to specific rows, which you specify in + Python. + +### Property 1: class_name + +The Stylekit is a collection of pre-defined CSS classes created by Taipy. It offers a simple way +to personalize the appearance of your Taipy web application, and it's user-friendly, even for +those who have no knowledge of CSS. + +We achieved this by just putting the **rows-bordered** Stylekit CSS class into the `class_name` +property of the table control: + +```python +main_md = Markdown("<|{food_df}|table|class_name=rows-bordered|>") +``` + +To learn more about how Stylekit supports Taipy tables, you can check the documentation +[here](../../../manuals/gui/viselements/table.md#styling). If you want to explore the +many features of Stylekit beyond tables in Taipy, you can read this helpful +[tip article](../../tips/css_style_kit/index.md)! + +In addition to the handy pre-defined Stylekit classes, you also have the option to define and +use your own CSS classes. To do this, you can create a CSS file containing your custom style +sheet code and provide the file path as a string to the *css_name* parameter of the `Gui` object. + +Alternatively, you can follow an easier approach by naming the CSS file the same as your Python +script (but changing the extension to .css) and placing it in the same directory as the Python +script. For example, if your Taipy application code is in `main.py`, your CSS code can go in +`main.css` in the same directory. You can find more details about this +[here](../../../manuals/gui/styling/index.md#style-sheets). + +### Property 2: style + +To have more precise control over our styling, we can utilize the style property of tables +to assign CSS classes to individual rows in the table. For instance, we can assign a +user-defined **highlight-row** CSS class to rows where the **Category** column is **Dessert** to +give them a yellow background. + +![Property style](using_tables_3.png){width=70%} + +The style property accepts a function. This function is applied to each row of the table and +returns a string specifying the CSS class to be used for that particular row. To create the +table mentioned above, you can use the following code: + +```python title="main.py" +def table_style(state, index, row): + return "highlight-row" if row.Category == "Dessert" else "" + +table_properties = { + "class_name": "rows-bordered rows-similar", # optional + "style": table_style, +} + +main_md = Markdown("<|{food_df}|table|properties=table_properties|>") +# or Markdown("<|{food_df}|table|class_name=rows-bordered rows-similar|style=table_style|>") +``` + +```css +/* main.css */ +.highlight-row td { + background-color: yellow; +} +``` + +In our code, we also made use of the *class_name* property mentioned earlier, and we applied +two Stylekit table classes: **rows-bordered** and **rows-similar**. The **rows-similar** class +removes the default 0.5 opacity from odd rows. While it wasn't necessary, using it does enhance +the table's appearance when applying our **highlight-row** style. + +## Modifying Data + +Tables offer various properties for modifying data within the table. Notably, the *on_edit*, +*on_add*, and *on_delete* properties can receive user-defined **callback** functions. This +function is executed when you interact with the table, but it only appears when you specify the +relevant data modification property. + +Taipy doesn't come with default functions for these properties, so we'll define each function +ourselves to match our specific needs. We're also including the +[notify](../../../manuals/gui/notifications.md) function within our data modification callback +functions to send notifications to the user about their changes. + +## Editing (*on_edit*) + +When the *on_edit* property is used, new buttons with a pencil icon are added to each cell. +Clicking it allows the user to modify the value of that cell, +then clicking the tick triggers the callback function: + +![Editing](tables-on_edit.gif){width=100%} + +The following code can be used to implement basic editing functionality: + +```python +def food_df_on_edit(state, var_name, payload): + index = payload["index"] # row index + col = payload["col"] # column name + value = payload["value"] # new value cast to the column type + user_value = payload["user_value"] # new value as entered by the user + + # state.food_df.loc[index, col] = value # Don't do this! + old_value = state.food_df.loc[index, col] + new_food_df = state.food_df.copy() + new_food_df.loc[index, col] = value + state.food_df = new_food_df + notify(state, "I", f"Edited value from '{old_value}' to '{value}'. (index '{index}', column '{col}')") + +main_md = Markdown("<|{food_df}|table|on_edit=food_df_on_edit|>") +``` + +The table documentation provides more information on the function signature which is slightly +different for each data modification property. The code example above is self-explanatory though. + +Notice that we did not modify the *food_df* DataFrame with `state.food_df.loc[index, col] = value`. +This is because state variables should be updated by assignment to the variable itself hence why +we instead create a copy of the DataFrame, modify the relevant cell, then assign it back to +*state.food_df*. + +## Adding (*on_add*) + +Adding and deleting are quite similar to editing. When you specify the *on_add* property, a +`button` with a 'plus' icon is included, and when clicked, it triggers the defined *on_add* +callback function. + +![Adding](tables-on_add.gif){width=100%} + +We can implement the functionality above as follows: + +```python +def food_df_on_add(state, var_name, payload): + empty_row = pd.DataFrame([[None for _ in state.food_df.columns]], columns=state.food_df.columns) + state.food_df = pd.concat([empty_row, state.food_df], axis=0, ignore_index=True) + + notify(state, "S", f"Added a new row.") + +main_md = Markdown("<|{food_df}|table|on_add=food_df_on_add|>") +``` + +This code simply adds a new empty row to the top of the table (DataFrame). +You can customize the callback function accordingly if your use case requires +some columns to have a default or set value. + +## Deleting (*on_delete*) + +Finally, the deletion process works as follows: + +![Deleting](tables-on_delete.gif){width=100%} + +We can implement basic functionality with the following code: + +```python +def food_df_on_delete(state, var_name, payload): + index = payload["index"] # row index + + state.food_df = state.food_df.drop(index=index) + notify(state, "E", f"Deleted row at index '{index}'") + +main_md = Markdown("<|{food_df}|table|on_delete=food_df_on_delete|>") +``` + +## Complete Code + +Once more, please note that this tip article doesn't cover all the features of tables in Taipy +comprehensively. If you're seeking a feature that we didn't address here, be sure to refer to +the [documentation](../../../manuals/gui/viselements/table.md) for more information! + +Lastly, here's the code that combines all the features we discussed in this article, +used to create the application shown at the beginning of the article: + +```python +from taipy.gui import Gui, Markdown, notify +import pandas as pd + + +food_df = pd.DataFrame({ + "Meal": ["Lunch", "Dinner", "Lunch", "Lunch", "Breakfast", "Breakfast", "Lunch", "Dinner"], + "Category": ["Food", "Food", "Drink", "Food", "Food", "Drink", "Dessert", "Dessert"], + "Name": ["Burger", "Pizza", "Soda", "Salad", "Pasta", "Water", "Ice Cream", "Cake"], + "Calories": [300, 400, 150, 200, 500, 0, 400, 500], +}) + + +def food_df_on_edit(state, var_name, payload): + index = payload["index"] # row index + col = payload["col"] # column name + value = payload["value"] # new value cast to the column type + user_value = payload["user_value"] # new value as entered by the user + + old_value = state.food_df.loc[index, col] + new_food_df = state.food_df.copy() + new_food_df.loc[index, col] = value + state.food_df = new_food_df + notify(state, "I", f"Edited value from '{old_value}' to '{value}'. (index '{index}', column '{col}')") + + +def food_df_on_delete(state, var_name, payload): + index = payload["index"] # row index + + state.food_df = state.food_df.drop(index=index) + notify(state, "E", f"Deleted row at index '{index}'") + + +def food_df_on_add(state, var_name, payload): + empty_row = pd.DataFrame([[None for _ in state.food_df.columns]], columns=state.food_df.columns) + state.food_df = pd.concat([empty_row, state.food_df], axis=0, ignore_index=True) + + notify(state, "S", f"Added a new row.") + + +table_properties = { + "class_name": "rows-bordered", + "filter": True, + "on_edit": food_df_on_edit, + "on_delete": food_df_on_delete, + "on_add": food_df_on_add, + "group_by[Category]": True, + "apply[Calories]": "sum", +} + + +main_md = Markdown(""" +# Daily Calorie Tracker + +<|{food_df}|table|properties=table_properties|> +""") + +Gui(page=main_md).run() +``` diff --git a/docs/knowledge_base/tips/using_tables/tables-filter.gif b/docs/knowledge_base/tips/using_tables/tables-filter.gif new file mode 100644 index 000000000..8abf66b45 Binary files /dev/null and b/docs/knowledge_base/tips/using_tables/tables-filter.gif differ diff --git a/docs/knowledge_base/tips/using_tables/tables-full-demo-1.gif b/docs/knowledge_base/tips/using_tables/tables-full-demo-1.gif new file mode 100644 index 000000000..eb8ed21e4 Binary files /dev/null and b/docs/knowledge_base/tips/using_tables/tables-full-demo-1.gif differ diff --git a/docs/knowledge_base/tips/using_tables/tables-on_add.gif b/docs/knowledge_base/tips/using_tables/tables-on_add.gif new file mode 100644 index 000000000..6fcc7b85a Binary files /dev/null and b/docs/knowledge_base/tips/using_tables/tables-on_add.gif differ diff --git a/docs/knowledge_base/tips/using_tables/tables-on_delete.gif b/docs/knowledge_base/tips/using_tables/tables-on_delete.gif new file mode 100644 index 000000000..e8cd283c4 Binary files /dev/null and b/docs/knowledge_base/tips/using_tables/tables-on_delete.gif differ diff --git a/docs/knowledge_base/tips/using_tables/tables-on_edit.gif b/docs/knowledge_base/tips/using_tables/tables-on_edit.gif new file mode 100644 index 000000000..c6b729920 Binary files /dev/null and b/docs/knowledge_base/tips/using_tables/tables-on_edit.gif differ diff --git a/docs/knowledge_base/tips/using_tables/using_tables.png b/docs/knowledge_base/tips/using_tables/using_tables.png new file mode 100644 index 000000000..766a18740 Binary files /dev/null and b/docs/knowledge_base/tips/using_tables/using_tables.png differ diff --git a/docs/knowledge_base/tips/using_tables/using_tables_2.png b/docs/knowledge_base/tips/using_tables/using_tables_2.png new file mode 100644 index 000000000..c0c62a204 Binary files /dev/null and b/docs/knowledge_base/tips/using_tables/using_tables_2.png differ diff --git a/docs/knowledge_base/tips/using_tables/using_tables_3.png b/docs/knowledge_base/tips/using_tables/using_tables_3.png new file mode 100644 index 000000000..8df449be0 Binary files /dev/null and b/docs/knowledge_base/tips/using_tables/using_tables_3.png differ diff --git a/docs/knowledge_base/tutorials/complete_application/index.md b/docs/knowledge_base/tutorials/complete_application/index.md index 17522d585..61fa7d637 100644 --- a/docs/knowledge_base/tutorials/complete_application/index.md +++ b/docs/knowledge_base/tutorials/complete_application/index.md @@ -1,4 +1,4 @@ -!!! important "Supported Python versions" +!!! note "Supported Python versions" Taipy requires **Python 3.8** or newer. diff --git a/docs/knowledge_base/tutorials/complete_application/step_01/step_01.md b/docs/knowledge_base/tutorials/complete_application/step_01/step_01.md index bc9fb884c..bb45188ed 100644 --- a/docs/knowledge_base/tutorials/complete_application/step_01/step_01.md +++ b/docs/knowledge_base/tutorials/complete_application/step_01/step_01.md @@ -1,7 +1,8 @@ > The full code is available here. -This is a guide for creating a Data Visualization page for our example. The page includes interactive visual elements for showcasing data from a CSV file. +This is a guide for creating a Data Visualization page for our example. The page includes +interactive visual elements for showcasing data from a CSV file. ![Interactive GUI](result.gif){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } @@ -23,12 +24,15 @@ dataset = get_data(path_to_csv) ## Visual Elements -Taipy introduces the concept of *Visual elements*, which are graphic objects shown on the client interface. You can use various visual elements such as [slider](../../../../manuals/gui/viselements/slider.md), a +Taipy introduces the concept of *Visual elements*, which are graphic objects shown on the client +interface. You can use various visual elements such as a +[slider](../../../../manuals/gui/viselements/slider.md), a [chart](../../../../manuals/gui/viselements/chart.md), a [table](../../../../manuals/gui/viselements/table.md), an [input](../../../../manuals/gui/viselements/input.md), a [menu](../../../../manuals/gui/viselements/menu.md), etc. Check the list -[here](../../../../manuals/gui/viselements/index.md). The syntax for adding a visual element is as follows: +[here](../../../../manuals/gui/viselements/index.md). The syntax for adding a visual element is +as follows: ```markdown <|{variable}|visual_element_name|param_1=param_1|param_2=param_2| ... |> @@ -56,19 +60,23 @@ The Data Visualization page includes the following visual elements: ## Multi-client - state -Taipy maintains a distinct state for every client connection. This state stores the values of all variables used in the user interface. For example, modifying *n_week* through a slider will +Taipy maintains a distinct state for every client connection. This state stores the values of +all variables used in the user interface. For example, modifying *n_week* through a slider will update *state.n_week*, not the global Python variable *n_week*. Each client has its own state, ensuring that changes made by one client don't affect others. -## [Callbacks](../../../../manuals/gui/callbacks.md) +## Callbacks -You can include callbacks in each visual element, enabling you to modify variables according to user actions. For further details, explore local callbacks and global callbacks. +Most visual element include [callbacks](../../../../manuals/gui/callbacks.md), +enabling you to modify variables according to user actions. For further details, explore local +callbacks and global callbacks. - *state*: The state object containing all the variables. - The name of the modified variable. (optional) - Its new value. (optional) -Here's an example of `on_change()` function to update *state.dataset_week* based on the selected week from the slider: +Here's an example of of setting the `on_change` callback function to update *state.dataset_week* based on the selected +week from the slider: ```markdown <|{n_week}|slider|min=1|max=52|on_change=on_slider|> @@ -81,7 +89,8 @@ def on_slider(state): # Markdown -The following Markdown corresponds to the `pages/data_viz/data_viz.md`file. It is the entire Markdown of the first page. +The following Markdown corresponds to the `pages/data_viz/data_viz.md`file. It is the entire +Markdown of the first page. ```markdown # Data Visualization page @@ -95,7 +104,9 @@ Select week: *<|{n_week}|>* # Python code (pages/data_viz/data_viz.py) -The following Python code corresponds to the `pages/data_viz/data_viz.py` file. It is the code that complements the Markdown above. This code populates the objects on the page and creates the connection between the slider and the chart. +The following Python code corresponds to the `pages/data_viz/data_viz.py` file. It is the code +that complements the Markdown above. This code populates the objects on the page and creates the +connection between the slider and the chart. ```python from taipy.gui import Markdown diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/config.gif b/docs/knowledge_base/tutorials/cycles_scopes/config.gif similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/config.gif rename to docs/knowledge_base/tutorials/cycles_scopes/config.gif diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/config.svg b/docs/knowledge_base/tutorials/cycles_scopes/config.svg similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/config.svg rename to docs/knowledge_base/tutorials/cycles_scopes/config.svg diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/config.toml b/docs/knowledge_base/tutorials/cycles_scopes/config.toml similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/config.toml rename to docs/knowledge_base/tutorials/cycles_scopes/config.toml diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/config_scope.gif b/docs/knowledge_base/tutorials/cycles_scopes/config_scope.gif similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/config_scope.gif rename to docs/knowledge_base/tutorials/cycles_scopes/config_scope.gif diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/config_scope.svg b/docs/knowledge_base/tutorials/cycles_scopes/config_scope.svg similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/config_scope.svg rename to docs/knowledge_base/tutorials/cycles_scopes/config_scope.svg diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/index.md b/docs/knowledge_base/tutorials/cycles_scopes/index.md similarity index 83% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/index.md rename to docs/knowledge_base/tutorials/cycles_scopes/index.md index d127c68fe..d3c1fdf6e 100644 --- a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/index.md +++ b/docs/knowledge_base/tutorials/cycles_scopes/index.md @@ -10,35 +10,39 @@ Two datasets have also to be downloaded ( *Estimated Time for Completion: 30 minutes; Difficulty Level: Intermediate* In this section, we will explore the intricate relationship between -[Scopes](../../../../manuals/core/concepts/scope.md) and -[Cycles](../../../../manuals/core/concepts/cycle.md), two core concepts -that helps manage data nodes and scenarios effectively in Taipy. +[Scopes](../../../manuals/core/concepts/scope.md) and +[Cycles](../../../manuals/core/concepts/cycle.md), two core concepts that help manage data +nodes and scenarios effectively in Taipy. # Cycles -[Cycles](../../../../manuals/core/concepts/cycle.md) have been introduced to reflect -business situations companies frequently encounter and can be extremely useful. +[Cycles](../../../manuals/core/concepts/cycle.md) have been introduced to reflect business +situations companies frequently encounter and can be extremely useful. -For example, a big fast-food chain wants to predict its store sales every week. When they create a scenario -for a particular week, it has to be linked to that specific week. Usually, there will be just one scenario -used for all the scenarios created for a particular week. +For example, a big fast-food chain wants to predict its store sales every week. When they create +a scenario for a particular week, it has to be linked to that specific week. Usually, there will +be just one scenario used for all the scenarios created for a particular week. This special 'official' scenario is called the 'Primary' scenario in Taipy. Note that Cycles can be ignored entirely if the business problem has no time frequency. ## Advantages of Cycles: -- **Time-Based Organization:** Cycles facilitate the organization and analysis of scenarios over specific periods. +- **Time-Based Organization:** Cycles facilitate the organization and analysis of scenarios over + specific periods. -- **Primary Scenario Identification:** Cycles allow the designation of a primary scenario for reference or official analysis. +- **Primary Scenario Identification:** Cycles allow the designation of a primary scenario for + reference or official analysis. - **Enhanced Data Consistency:** - They ensure data and parameter consistency across scenarios linked to a specific time period. + They ensure data and parameter consistency across scenarios linked to a specific time period. -- **Custom Frequency:** Cycles can be customized to various frequencies to align with specific business needs. +- **Custom Frequency:** Cycles can be customized to various frequencies to align with specific + business needs. -- **Scenario Comparison:** Cycles make it easier to compare and analyze different scenarios within the same time frame. +- **Scenario Comparison:** Cycles make it easier to compare and analyze different scenarios + within the same time frame. ## Example: Filtering by Month @@ -64,7 +68,7 @@ def filter_by_month(df, month): - Add the frequency property for the scenario and put "MONTHLY:FREQUENCY" (DAYLY, WEEKLY, MONTHLY, YEARLY) - - Load the new [configuration](../config.toml) in the code + - Load the new [configuration](./config.toml) in the code === "Python configuration" @@ -92,11 +96,12 @@ def filter_by_month(df, month): ``` -Since we have specified `frequency=Frequency.MONTHLY`, the corresponding scenario when -created, is automatically attached to the correct period (month). +Since we have specified `frequency=Frequency.MONTHLY`, the corresponding scenario when created, +is automatically attached to the correct period (month). -The Cycle which a Scenario belongs to is based on the _creation_date_ of the scenario. It can be "attached" -to a specific cycle by manually setting its _creation_date_, as we are doing in the following example. +The Cycle which a Scenario belongs to is based on the _creation_date_ of the scenario. It can be +"attached" to a specific cycle by manually setting its _creation_date_, as we are doing in the +following example. ```python @@ -110,9 +115,9 @@ scenario_2 = tp.create_scenario(scenario_cfg, name="Scenario 2022/10/5") ``` -Scenario 1 and Scenario 2 are two separate scenario entities created using the same scenario configuration. -They are part of the same Cycle but have different data nodes. By default, each scenario instance -has its own data node instances, and they are not shared with any other scenario. +Scenario 1 and Scenario 2 are two separate scenario entities created using the same scenario +configuration. They are part of the same Cycle but have different data nodes. By default, each +scenario instance has its own data node instances, and they are not shared with any other scenario. ## Interplay between Scopes and Cycles @@ -122,7 +127,8 @@ hand, determines how data nodes are shared within these cycles and scenarios. # Scopes Sharing data nodes between entities allows you to organize and manage your data better. -It avoids data dupplications and allows Taipy to better manage execution (see [skippable tasks](...)). +It avoids data duplications and allows Taipy to better manage execution (see +[skippable tasks](../../tips/skippable_tasks/index.md)). The developer may decide: - `Scope.SCENARIO` (_default_): Having one data node for each scenario. @@ -168,7 +174,8 @@ Let's change the configuration of our data nodes: ``` -Defining the _month_ of scenario 1 will also determine the _month_ of scenario 2 since they share the same Data Node. +Defining the _month_ of scenario 1 will also determine the _month_ of scenario 2 since they +share the same Data Node. ```python scenario_1.month.write(10) @@ -188,7 +195,8 @@ Month Data Node of Scenario 2: 10 ``` In this unusual example where both scenarios are in the same cycle and all their data nodes -are at least with a Cycle Scope, executing one is the same as executing the other as they share all their data nodes. +are at least with a Cycle Scope, executing one is the same as executing the other as they share +all their data nodes. # Going further into Cycles @@ -201,7 +209,7 @@ first scenario created for a cycle is primary. ### Python code associated to primary scenarios -[`tp.set_primary()`](../../../../manuals/core/entities/scenario-cycle-mgt.md#promote-a-scenario-as-primary) +[`tp.set_primary()`](../../../manuals/core/entities/scenario-cycle-mgt.md#promote-a-scenario-as-primary) allows changing the primary scenario in a Cycle. `.is_primary` identifies as a boolean whether the scenario is primary or not. @@ -234,10 +242,10 @@ Scenario 2: Primary? False True - `tp.get_primary()`: returns the primary scenario of the Cycle. -### GUI-Core visual elements +### Scenario management visual elements -You can utilize GUI-Core elements to control Cycles. Cycles can be seen in either the -*scenario_selector* or *data_node_selector*. Additionally, it's possible to designate a scenario +You can use Scenario management visual elements to control Cycles. Cycles can be seen in either the + `scenario_selector` or `data_node_selector`. Additionally, it's possible to designate a scenario as primary directly through the `scenario` visual element. ```python diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/scope_and_cycle.py b/docs/knowledge_base/tutorials/cycles_scopes/scope_and_cycle.py similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/scope_and_cycle.py rename to docs/knowledge_base/tutorials/cycles_scopes/scope_and_cycle.py diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/scope_and_cycle_toml.py b/docs/knowledge_base/tutorials/cycles_scopes/scope_and_cycle_toml.py similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/scope_and_cycle_toml.py rename to docs/knowledge_base/tutorials/cycles_scopes/scope_and_cycle_toml.py diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/time_series.csv b/docs/knowledge_base/tutorials/cycles_scopes/time_series.csv similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/time_series.csv rename to docs/knowledge_base/tutorials/cycles_scopes/time_series.csv diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_04/time_series_2.csv b/docs/knowledge_base/tutorials/cycles_scopes/time_series_2.csv similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_04/time_series_2.csv rename to docs/knowledge_base/tutorials/cycles_scopes/time_series_2.csv diff --git a/docs/knowledge_base/tutorials/data_nodes.md b/docs/knowledge_base/tutorials/execution.md similarity index 100% rename from docs/knowledge_base/tutorials/data_nodes.md rename to docs/knowledge_base/tutorials/execution.md diff --git a/docs/knowledge_base/tutorials/images/icon-code.svg b/docs/knowledge_base/tutorials/images/icon-code.svg new file mode 100644 index 000000000..df337b3bb --- /dev/null +++ b/docs/knowledge_base/tutorials/images/icon-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/knowledge_base/tutorials/images/icon-video.svg b/docs/knowledge_base/tutorials/images/icon-video.svg new file mode 100644 index 000000000..5132b3206 --- /dev/null +++ b/docs/knowledge_base/tutorials/images/icon-video.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/knowledge_base/tutorials/index.md b/docs/knowledge_base/tutorials/index.md index 64ae02ead..fe948b4e4 100644 --- a/docs/knowledge_base/tutorials/index.md +++ b/docs/knowledge_base/tutorials/index.md @@ -1,3 +1,228 @@ -# Tutorial videos +--- +hide: + - toc +--- -Let's explore what you can learn with Taipy by watching the tutorial videos below. +# Tutorials + +Follow our tutorials and get the core concepts of Taipy. + + +
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
+ + \ No newline at end of file diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_07/config.svg b/docs/knowledge_base/tutorials/job_execution/config.svg similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_07/config.svg rename to docs/knowledge_base/tutorials/job_execution/config.svg diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_07/config.toml b/docs/knowledge_base/tutorials/job_execution/config.toml similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_07/config.toml rename to docs/knowledge_base/tutorials/job_execution/config.toml diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_07/index.md b/docs/knowledge_base/tutorials/job_execution/index.md similarity index 97% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_07/index.md rename to docs/knowledge_base/tutorials/job_execution/index.md index bad2cce58..6888ec47b 100644 --- a/docs/knowledge_base/tutorials/scenario_management_overview/step_07/index.md +++ b/docs/knowledge_base/tutorials/job_execution/index.md @@ -9,7 +9,7 @@ with the *Estimated Time for Completion: 15 minutes; Difficulty Level: Advanced* -Taipy has [different ways](../../../../manuals/core/config/job-config.md) to execute the code. +Taipy has [different ways](../../../manuals/core/config/job-config.md) to execute the code. Changing the execution mode can be useful for running multiple tasks in parallel. - _standalone_ mode: asynchronous. Jobs can be run in parallel depending on the graph of execution (if _max_nb_of_workers_ > 1). diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_07/job_execution.py b/docs/knowledge_base/tutorials/job_execution/job_execution.py similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_07/job_execution.py rename to docs/knowledge_base/tutorials/job_execution/job_execution.py diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_07/job_execution_toml.py b/docs/knowledge_base/tutorials/job_execution/job_execution_toml.py similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_07/job_execution_toml.py rename to docs/knowledge_base/tutorials/job_execution/job_execution_toml.py diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_08/config.svg b/docs/knowledge_base/tutorials/scenario_comparison/config.svg similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_08/config.svg rename to docs/knowledge_base/tutorials/scenario_comparison/config.svg diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_08/index.md b/docs/knowledge_base/tutorials/scenario_comparison/index.md similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_08/index.md rename to docs/knowledge_base/tutorials/scenario_comparison/index.md diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_08/scenario_comparison.py b/docs/knowledge_base/tutorials/scenario_comparison/scenario_comparison.py similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_08/scenario_comparison.py rename to docs/knowledge_base/tutorials/scenario_comparison/scenario_comparison.py diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/.gitkeep b/docs/knowledge_base/tutorials/scenario_management_overview/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_01/config.gif b/docs/knowledge_base/tutorials/scenario_management_overview/config.gif similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_01/config.gif rename to docs/knowledge_base/tutorials/scenario_management_overview/config.gif diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_01/config.mp4 b/docs/knowledge_base/tutorials/scenario_management_overview/config.mp4 similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_01/config.mp4 rename to docs/knowledge_base/tutorials/scenario_management_overview/config.mp4 diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_01/config.svg b/docs/knowledge_base/tutorials/scenario_management_overview/config.svg similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_01/config.svg rename to docs/knowledge_base/tutorials/scenario_management_overview/config.svg diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_01/config.toml b/docs/knowledge_base/tutorials/scenario_management_overview/config.toml similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_01/config.toml rename to docs/knowledge_base/tutorials/scenario_management_overview/config.toml diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_01/demo.gif b/docs/knowledge_base/tutorials/scenario_management_overview/demo.gif similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_01/demo.gif rename to docs/knowledge_base/tutorials/scenario_management_overview/demo.gif diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/index.md b/docs/knowledge_base/tutorials/scenario_management_overview/index.md index 8ee20677a..46f101652 100644 --- a/docs/knowledge_base/tutorials/scenario_management_overview/index.md +++ b/docs/knowledge_base/tutorials/scenario_management_overview/index.md @@ -1,47 +1,281 @@ -!!! important "Supported Python versions" +> You can download the code +here. Here is the +Python version +with the +TOML file - Taipy requires **Python 3.8** or newer. +*Estimated Time for Completion: 15 minutes; Difficulty Level: Beginner* -Welcome to the **Scenario management** tutorial guide. +By the end of this tutorial, you will have all the bases to create a little application using the +scenario management of Taipy. -The Taipy Scenario management is a set of functionalities used to easily and efficiently -create dataflows (pipelines), manage and record their executions, and access their data. -It is designed to be used by end-users in a multi-user context and gets especially useful -for Machine Learning or Mathematical optimization. +![Scenario management demo](demo.gif){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } -# Before we begin +Before looking at some code examples, to apprehend what is a *Scenario*, you need to +understand the *Data node* and *Task* concepts. -Only Taipy has to be installed. **Taipy** package requires Python 3.8 or newer; +- [**Data Nodes**](../../../manuals/core/concepts/data-node.md): represents a variable in Taipy. +Data Nodes don't contain the data itself but point to the data and know + how to retrieve it. These Data Nodes can point to different types of data sources like CSV + files, Pickle files, databases, etc., and they can represent various types of Python variables + such as integers, strings, data frames, lists, and more. They are fully generic and can be + used to represent datasets, parameters, KPIs, intermediate data, or any variable. -``` console -$ pip install taipy +- [**Tasks**](../../../manuals/core/concepts/task.md): are the translation of functions in + Taipy where their inputs and outputs are data nodes. + +- [**Scenarios**](../../../manuals/core/concepts/scenario.md): Scenarios are created by + combining Data Nodes and Tasks to form a graph that maps the execution flow. Each scenario can be + submitted, resulting in the execution of its tasks. + End-Users very often require modifying various parameters to reflect different business + situations. Taipy provide the framework to execute various scenarios under different + situations (i.e. various data/parameters values set by end-users). + +[**Configuration**](../../../manuals/core/config/index.md) is a structure to define scenarios. +It serves as the blueprint for our Directed Acyclic Graph(s) and models the data sources, +parameters, and tasks. After being defined, a configuration functions like a superclass and is +employed to generate various instances of scenarios. + +# Configuring a Scenario + +Think about the most basic pipeline: one function that needs two things to work – some data and a +date. It uses these to generate a prediction for that date. + +See the code for this function below: + +```python +import pandas as pd + +def predict(historical_temperature: pd.DataFrame, date_to_forecast: str) -> float: + print(f"Running baseline...") + historical_temperature['Date'] = pd.to_datetime(historical_temperature['Date']) + historical_same_day = historical_temperature.loc[ + (historical_temperature['Date'].dt.day == date_to_forecast.day) & + (historical_temperature['Date'].dt.month == date_to_forecast.month) + ] + return historical_same_day['Temp'].mean() ``` +The scenario can be represented as the following graph: + +![Simple scenario](config.svg){ width=700 style="margin:auto;display:block;border: 4px solid rgb (210,210,210);border-radius:7px" } + +Three Data Nodes are being configured (**historical_temperature**, **date_to_forecast** and +**predictions**). The task **predict** links the three Data Nodes through the Python function. + +!!! example "Configuration" + + === "Python configuration" + + **Alternative 1:** Configuration using Python Code + + Here is the code to configure a simple scenario. + + ```python + # Configuration of Data Nodes + historical_temperature_cfg = Config.configure_data_node("historical_temperature") + date_to_forecast_cfg = Config.configure_data_node("date_to_forecast") + predictions_cfg = Config.configure_data_node("predictions") + + # Configuration of tasks + predict_cfg = Config.configure_task(id="predict", + function=predict, + input=[historical_temperature_cfg, date_to_forecast_cfg], + output=predictions_cfg) + + # Configuration of scenario + scenario_cfg = Config.configure_scenario(id="my_scenario", task_configs=[predict_cfg]) + ``` + + === "Using Taipy Studio" + + **Alternative 2:** Configuration using Taipy Studio + + By watching the animation below, you can see how this configuration gets created using + Taipy Studio. In fact, Taipy Studio is an editor of a TOML file specific to Taipy. It + lets you edit and view a TOML file that will be used in our code. + + + + To use this configuration in our code (`main.py` for example), we must load it and + retrieve the *scenario_cfg* instance. This object is the basis to instantiate our + scenarios. + + ```python + Config.load('config.toml') + + # my_scenario is the id of the scenario configured + scenario_cfg = Config.scenarios['my_scenario'] + ``` + +The configuration is done! Let's use it to instantiate scenarios and submit them. + +# Instantiate Scenario + +First, run the Core service in your code (`tp.Core().run()`). Then, you can play with Taipy: + +- create scenarios, + +- write your input data nodes, + +- submit them to run the task + +- read your output data node. + +Creating a scenario (`tp.create_scenario()`) creates all its related entities +(**tasks**, **Data Nodes**, etc). These entities are being created thanks to the previous +configuration. Still, no scenario has been run yet. `tp.submit()` is the line of code +that triggers the run of all the scenario-related tasks. + +```python +import taipy as tp + +# Run of the Core +tp.Core().run() + +# Creation of the scenario and execution +scenario = tp.create_scenario(scenario_cfg) +scenario.historical_temperature.write(data) +scenario.date_to_forecast.write(dt.datetime.now()) +tp.submit(scenario) + +print("Value at the end of task", scenario.predictions.read()) +``` + +Results: + +``` +[2022-12-22 16:20:02,740][Taipy][INFO] job JOB_predict_... is completed. +Value at the end of task 23.45 +``` + +In this code, you can see how to create and submit scenarios, retrieve data nodes, +read and write data. Many other functions are described in the manuals, in particular in the +[taipy](../../../manuals/reference/pkg_taipy.md), +[scenario](../../../manuals/core/entities/scenario-cycle-mgt.md) and +[data node](../../../manuals/core/entities/data-node-mgt.md) documentation pages. + +# Visual elements + +The small piece of code of the previous section shows how to manage scenarios. The scenario or data +node management is usually done by end-users through a graphical interface. Taipy provides +visual elements dedicated to Scenario management to replace the code above. + +Add these few lines to the code of your script. This creates a web application, so end-users can: + +- select scenarios, + +- create new ones, + +- submit them, + +- access their properties. + +```python +import taipy as tp + +def save(state): + # write values of Data Node to submit scenario + state.scenario.historical_temperature.write(data) + state.scenario.date_to_forecast.write(state.date) + tp.gui.notify(state, "s", "Saved! Ready to submit") + +date = None +scenario_md = """ +<|{scenario}|scenario_selector|> + +Put a Date +<|{date}|date|on_change=save|active={scenario}|> + +Run the scenario +<|{scenario}|scenario|> +<|{scenario}|scenario_dag|> + +View all the information on your prediction here +<|{scenario.predictions if scenario else None}|data_node|> +""" + +tp.Gui(scenario_md).run() +``` + +The +[Scenario management controls](../../../manuals/gui/viselements/controls.md#scenario-management-controls) +http://127.0.0.1:8000/en/develop/manuals/ +provide all the necessary features to access and manage scenarios and data nodes. In fact, +creating a Scenario based application connected to your pipelines has never been simpler. + +![Scenario management demo](demo.gif){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } + +# Entire code + +```python +from taipy import Config +import taipy as tp +import pandas as pd +import datetime as dt + + +data = pd.read_csv("https://raw.githubusercontent.com/Avaiga/taipy-getting-started-core/develop/src/daily-min-temperatures.csv") + + +# Normal function used by Taipy +def predict(historical_temperature: pd.DataFrame, date_to_forecast: str) -> float: + print(f"Running baseline...") + historical_temperature['Date'] = pd.to_datetime(historical_temperature['Date']) + historical_same_day = historical_temperature.loc[ + (historical_temperature['Date'].dt.day == date_to_forecast.day) & + (historical_temperature['Date'].dt.month == date_to_forecast.month) + ] + return historical_same_day['Temp'].mean() + +# Configuration of Data Nodes +historical_temperature_cfg = Config.configure_data_node("historical_temperature") +date_to_forecast_cfg = Config.configure_data_node("date_to_forecast") +predictions_cfg = Config.configure_data_node("predictions") -!!! info +# Configuration of tasks +predictions_cfg = Config.configure_task("predict", + predict, + [historical_temperature_cfg, date_to_forecast_cfg], + predictions_cfg) - `pip install taipy` is the preferred method to install the latest stable version of Taipy. - - If you don't have [pip](https://pip.pypa.io) installed, this - [Python installation guide](http://docs.python-guide.org/en/latest/starting/installation/) - can guide you through the process. +# Configuration of scenario +scenario_cfg = Config.configure_scenario(id="my_scenario", task_configs=[predictions_cfg]) +Config.export('config.toml') -# Taipy Studio +if __name__ == '__main__': + # Run of the Core + tp.Core().run() -You have two options for configuring Taipy: either through Python code or by using Taipy Studio. -Taipy Studio is a Visual Studio Code extension that offers a graphical editor for defining your -dataflows/pipelines. The configuration can be done easily and quickly with drag and drop. + # Creation of the scenario and execution + scenario = tp.create_scenario(scenario_cfg) + scenario.historical_temperature.write(data) + scenario.date_to_forecast.write(dt.datetime.now()) + tp.submit(scenario) -Now, without any more delay, let's get started with the coding! + print("Value at the end of task", scenario.predictions.read()) -# Concepts + def save(state): + state.scenario.historical_temperature.write(data) + state.scenario.date_to_forecast.write(state.date) + tp.gui.notify(state, "s", "Saved! Ready to submit") -1. [Scenario configuration and run](step_01/index.md) + date = None + scenario_md = """ +<|{scenario}|scenario_selector|> -2. [Cycles & Scopes](step_04/index.md) +Put a Date +<|{date}|date|on_change=save|active={scenario}|> -3. [Execution modes](step_07/index.md) +Run the scenario +<|{scenario}|scenario|> +<|{scenario}|scenario_dag|> -4. [Scenario comparison](step_08/index.md) +View all the information on your prediction here +<|{scenario.predictions if scenario else None}|data_node|> +""" -5. [Scenario subscription](step_09/index.md) + tp.Gui(scenario_md).run() +``` diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_01/scenario_management.py b/docs/knowledge_base/tutorials/scenario_management_overview/scenario_management.py similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_01/scenario_management.py rename to docs/knowledge_base/tutorials/scenario_management_overview/scenario_management.py diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_01/scenario_managemet_toml.py b/docs/knowledge_base/tutorials/scenario_management_overview/scenario_managemet_toml.py similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_01/scenario_managemet_toml.py rename to docs/knowledge_base/tutorials/scenario_management_overview/scenario_managemet_toml.py diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_01/index.md b/docs/knowledge_base/tutorials/scenario_management_overview/step_01/index.md deleted file mode 100644 index 8fe1cf374..000000000 --- a/docs/knowledge_base/tutorials/scenario_management_overview/step_01/index.md +++ /dev/null @@ -1,281 +0,0 @@ -> You can download the code -here. Here is the -Python version -with the -TOML file - -*Estimated Time for Completion: 15 minutes; Difficulty Level: Beginner* - -By the end of this tutorial, you will have all the bases to create a little application using the -scenario management of Taipy. - -![Scenario management demo](demo.gif){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } - -Before looking at some code examples, to apprehend what is a *Scenario*, you need to -understand the *Data node* and *Task* concepts. - -- [**Data Nodes**](../../../../manuals/core/concepts/data-node.md): represents a variable in Taipy. -Data Nodes don't contain the data itself but point to the data and know - how to retrieve it. These Data Nodes can point to different types of data sources like CSV - files, Pickle files, databases, etc., and they can represent various types of Python variables - such as integers, strings, data frames, lists, and more. They are fully generic and can be - used to represent datasets, parameters, KPIs, intermediate data, or any variable. - -- [**Tasks**](../../../../manuals/core/concepts/task.md): are the translation of functions in - Taipy where their inputs and outputs are data nodes. - -- [**Scenarios**](../../../../manuals/core/concepts/scenario.md): Scenarios are created by - combining Data Nodes and Tasks to form a graph that maps the execution flow. Each scenario can be - submitted, resulting in the execution of its tasks. - End-Users very often require modifying various parameters to reflect different business - situations. Taipy provide the framework to execute various scenarios under different - situations (i.e. various data/parameters values set by end-users). - -[**Configuration**](../../../../manuals/core/config/index.md) is a structure to define scenarios. -It serves as the blueprint for our Directed Acyclic Graph(s) and models the data sources, -parameters, and tasks. After being defined, a configuration functions like a superclass and is -employed to generate various instances of scenarios. - -# Configuring a Scenario - -Think about the most basic pipeline: one function that needs two things to work – some data and a -date. It uses these to generate a prediction for that date. - -See the code for this function below: - -```python -import pandas as pd - -def predict(historical_temperature: pd.DataFrame, date_to_forecast: str) -> float: - print(f"Running baseline...") - historical_temperature['Date'] = pd.to_datetime(historical_temperature['Date']) - historical_same_day = historical_temperature.loc[ - (historical_temperature['Date'].dt.day == date_to_forecast.day) & - (historical_temperature['Date'].dt.month == date_to_forecast.month) - ] - return historical_same_day['Temp'].mean() -``` -The scenario can be represented as the following graph: - -![Simple scenario](config.svg){ width=700 style="margin:auto;display:block;border: 4px solid rgb (210,210,210);border-radius:7px" } - -Three Data Nodes are being configured (**historical_temperature**, **date_to_forecast** and -**predictions**). The task **predict** links the three Data Nodes through the Python function. - -!!! example "Configuration" - - === "Python configuration" - - **Alternative 1:** Configuration using Python Code - - Here is the code to configure a simple scenario. - - ```python - # Configuration of Data Nodes - historical_temperature_cfg = Config.configure_data_node("historical_temperature") - date_to_forecast_cfg = Config.configure_data_node("date_to_forecast") - predictions_cfg = Config.configure_data_node("predictions") - - # Configuration of tasks - predict_cfg = Config.configure_task(id="predict", - function=predict, - input=[historical_temperature_cfg, date_to_forecast_cfg], - output=predictions_cfg) - - # Configuration of scenario - scenario_cfg = Config.configure_scenario(id="my_scenario", task_configs=[predict_cfg]) - ``` - - === "Using Taipy Studio" - - **Alternative 2:** Configuration using Taipy Studio - - By watching the animation below, you can see how this configuration gets created using - Taipy Studio. In fact, Taipy Studio is an editor of a TOML file specific to Taipy. It - lets you edit and view a TOML file that will be used in our code. - - - - To use this configuration in our code (`main.py` for example), we must load it and - retrieve the *scenario_cfg* instance. This object is the basis to instantiate our - scenarios. - - ```python - Config.load('config.toml') - - # my_scenario is the id of the scenario configured - scenario_cfg = Config.scenarios['my_scenario'] - ``` - -The configuration is done! Let's use it to instantiate scenarios and submit them. - -# Instantiate Scenario - -First, run the Core service in your code (`tp.Core().run()`). Then, you can play with Taipy: - -- create scenarios, - -- write your input data nodes, - -- submit them to run the task - -- read your output data node. - -Creating a scenario (`tp.create_scenario()`) creates all its related entities -(**tasks**, **Data Nodes**, etc). These entities are being created thanks to the previous -configuration. Still, no scenario has been run yet. `tp.submit()` is the line of code -that triggers the run of all the scenario-related tasks. - -```python -import taipy as tp - -# Run of the Core -tp.Core().run() - -# Creation of the scenario and execution -scenario = tp.create_scenario(scenario_cfg) -scenario.historical_temperature.write(data) -scenario.date_to_forecast.write(dt.datetime.now()) -tp.submit(scenario) - -print("Value at the end of task", scenario.predictions.read()) -``` - -Results: - -``` -[2022-12-22 16:20:02,740][Taipy][INFO] job JOB_predict_... is completed. -Value at the end of task 23.45 -``` - -In this code, you can see how to create and submit scenarios, retrieve data nodes, -read and write data. Many other functions are described in the manuals, in particular in the -[taipy](../../../../manuals/reference/pkg_taipy.md), -[scenario](../../../../manuals/core/entities/scenario-cycle-mgt.md) and -[data node](../../../../manuals/core/entities/data-node-mgt.md) documentation pages. - -# Visual elements - -The small piece of code of the previous section shows how to manage scenarios. The scenario or data -node management is usually done by end-users through a graphical interface. Taipy provides -visual elements dedicated to Scenario management to replace the code above. - -Add these few lines to the code of your script. This creates a web application, so end-users can: - -- select scenarios, - -- create new ones, - -- submit them, - -- access their properties. - -```python -import taipy as tp - -def save(state): - # write values of Data Node to submit scenario - state.scenario.historical_temperature.write(data) - state.scenario.date_to_forecast.write(state.date) - tp.gui.notify(state, "s", "Saved! Ready to submit") - -date = None -scenario_md = """ -<|{scenario}|scenario_selector|> - -Put a Date -<|{date}|date|on_change=save|active={scenario}|> - -Run the scenario -<|{scenario}|scenario|> -<|{scenario}|scenario_dag|> - -View all the information on your prediction here -<|{scenario.predictions if scenario else None}|data_node|> -""" - -tp.Gui(scenario_md).run() -``` - -The -[Scenario management controls](../../../../manuals/gui/viselements/controls.md#scenario-management-controls) -http://127.0.0.1:8000/en/develop/manuals/ -provide all the necessary features to access and manage scenarios and data nodes. In fact, -creating a Scenario based application connected to your pipelines has never been simpler. - -![Scenario management demo](demo.gif){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } - -# Entire code - -```python -from taipy import Config -import taipy as tp -import pandas as pd -import datetime as dt - - -data = pd.read_csv("https://raw.githubusercontent.com/Avaiga/taipy-getting-started-core/develop/src/daily-min-temperatures.csv") - - -# Normal function used by Taipy -def predict(historical_temperature: pd.DataFrame, date_to_forecast: str) -> float: - print(f"Running baseline...") - historical_temperature['Date'] = pd.to_datetime(historical_temperature['Date']) - historical_same_day = historical_temperature.loc[ - (historical_temperature['Date'].dt.day == date_to_forecast.day) & - (historical_temperature['Date'].dt.month == date_to_forecast.month) - ] - return historical_same_day['Temp'].mean() - -# Configuration of Data Nodes -historical_temperature_cfg = Config.configure_data_node("historical_temperature") -date_to_forecast_cfg = Config.configure_data_node("date_to_forecast") -predictions_cfg = Config.configure_data_node("predictions") - -# Configuration of tasks -predictions_cfg = Config.configure_task("predict", - predict, - [historical_temperature_cfg, date_to_forecast_cfg], - predictions_cfg) - -# Configuration of scenario -scenario_cfg = Config.configure_scenario(id="my_scenario", task_configs=[predictions_cfg]) - -Config.export('config.toml') - -if __name__ == '__main__': - # Run of the Core - tp.Core().run() - - # Creation of the scenario and execution - scenario = tp.create_scenario(scenario_cfg) - scenario.historical_temperature.write(data) - scenario.date_to_forecast.write(dt.datetime.now()) - tp.submit(scenario) - - print("Value at the end of task", scenario.predictions.read()) - - def save(state): - state.scenario.historical_temperature.write(data) - state.scenario.date_to_forecast.write(state.date) - tp.gui.notify(state, "s", "Saved! Ready to submit") - - date = None - scenario_md = """ -<|{scenario}|scenario_selector|> - -Put a Date -<|{date}|date|on_change=save|active={scenario}|> - -Run the scenario -<|{scenario}|scenario|> -<|{scenario}|scenario_dag|> - -View all the information on your prediction here -<|{scenario.predictions if scenario else None}|data_node|> -""" - - tp.Gui(scenario_md).run() -``` diff --git a/docs/knowledge_base/tutorials/data_pipelines.md b/docs/knowledge_base/tutorials/scenario_mgt_concepts.md similarity index 100% rename from docs/knowledge_base/tutorials/data_pipelines.md rename to docs/knowledge_base/tutorials/scenario_mgt_concepts.md diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_09/config.svg b/docs/knowledge_base/tutorials/scenario_subscription/config.svg similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_09/config.svg rename to docs/knowledge_base/tutorials/scenario_subscription/config.svg diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_09/index.md b/docs/knowledge_base/tutorials/scenario_subscription/index.md similarity index 98% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_09/index.md rename to docs/knowledge_base/tutorials/scenario_subscription/index.md index fd854eae6..821b69acc 100644 --- a/docs/knowledge_base/tutorials/scenario_management_overview/step_09/index.md +++ b/docs/knowledge_base/tutorials/scenario_subscription/index.md @@ -6,7 +6,7 @@ *Estimated Time for Completion: 15 minutes; Difficulty Level: Advanced* To perform an action after a job status change, you can -[subscribe a function](../../../../manuals/core/entities/orchestrating-and-job-execution.md#subscribe-to-job-execution) +[subscribe a function](../../../manuals/core/entities/orchestrating-and-job-execution.md#subscribe-to-job-execution) to a scenario. When there is a status change, this function is triggered. This feature enables the creation of logs or specific events for the Taipy GUI. diff --git a/docs/knowledge_base/tutorials/scenario_management_overview/step_09/scenario_subscription.py b/docs/knowledge_base/tutorials/scenario_subscription/scenario_subscription.py similarity index 100% rename from docs/knowledge_base/tutorials/scenario_management_overview/step_09/scenario_subscription.py rename to docs/knowledge_base/tutorials/scenario_subscription/scenario_subscription.py diff --git a/docs/knowledge_base/tutorials/understanding_gui/index.md b/docs/knowledge_base/tutorials/understanding_gui/index.md index 5c3050305..b9d720256 100644 --- a/docs/knowledge_base/tutorials/understanding_gui/index.md +++ b/docs/knowledge_base/tutorials/understanding_gui/index.md @@ -1,8 +1,9 @@ -!!! important "Supported Python versions" +!!! note "Supported Python versions" Taipy requires **Python 3.8** or newer. -Welcome to the **Tutorial** for using Taipy frontend. This guide will demonstrate how to utilize Taipy to build an interactive web application. +Welcome to the **Tutorial** for using Taipy frontend. This guide will demonstrate how to utilize +Taipy to build an interactive web application. ![GUI application](step_07/result.png){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } @@ -14,9 +15,9 @@ Taipy aims to simplify web application development: - Offers intuitive visualization using Markdown syntax. -In each part of the **"Tutorial"** we'll emphasize the basic principles of *Taipy*. -It's important to note that each step builds on the code from the previous one. -By the end of the final step, you'll be equipped with the ability to create your own Taipy application. +In each part of the **"Tutorial"** we'll emphasize the basic principles of *Taipy*. It's +important to note that each step builds on the code from the previous one. By the end of the +final step, you'll be equipped with the ability to create your own Taipy application. ## Before we begin @@ -27,8 +28,8 @@ $ pip install taipy ``` Once you finish step 5, the application will include a Natural Language Processing (NLP) algorithm -for demonstration purposes. Note that this algorithm is compatible only with Python versions 3.8 to 3.10. -To incorporate this NLP feature, you'll need to install Transformers and Torch. +for demonstration purposes. Note that this algorithm is compatible only with Python versions 3.8 +to 3.10. To incorporate this NLP feature, you'll need to install Transformers and Torch. However, if you prefer, you can proceed with the tutorial guide without using this algorithm. ``` console @@ -46,11 +47,14 @@ $ pip install transformers ## Using Notebooks -This **Tutorial** is for Python scripts (*.py*) only. If you want to use **Jupyter Notebooks**, download this [notebook](../../../../getting_started/getting-started-gui/getting_started.ipynb). +This **Tutorial** is for Python scripts (*.py*) only. If you want to use **Jupyter Notebooks**, +download this [notebook](./getting_started.ipynb). ## Taipy Studio -[Taipy Studio](../../../manuals/studio/index.md) is a VS Code extension that provides an auto-completion of Taipy visual elements. Creating a Taipy application can be done more easily and quickly through Taipy Studio. +[Taipy Studio](../../../manuals/studio/index.md) is a VS Code extension that provides an +auto-completion of Taipy visual elements. Creating a Taipy application can be done more easily +and quickly through Taipy Studio. So, without further delay, let's begin to code! diff --git a/docs/knowledge_base/tutorials/understanding_gui/step_01/step_01.md b/docs/knowledge_base/tutorials/understanding_gui/step_01/step_01.md index d5976f006..cacb7d6a8 100644 --- a/docs/knowledge_base/tutorials/understanding_gui/step_01/step_01.md +++ b/docs/knowledge_base/tutorials/understanding_gui/step_01/step_01.md @@ -5,8 +5,7 @@ or all the steps here. !!! warning "For Notebooks" - The "Getting Started" Notebook is available - [here](../../../../getting_started/getting-started-gui/getting_started.ipynb). In Taipy GUI, + The Notebook is available [here](../getting_started.ipynb). In Taipy GUI, the process to execute a Jupyter Notebook is different from executing a Python Script. # Step 1: First Web page diff --git a/docs/knowledge_base/tutorials/understanding_gui/step_02/step_02.md b/docs/knowledge_base/tutorials/understanding_gui/step_02/step_02.md index 84e15694b..a41204003 100644 --- a/docs/knowledge_base/tutorials/understanding_gui/step_02/step_02.md +++ b/docs/knowledge_base/tutorials/understanding_gui/step_02/step_02.md @@ -4,18 +4,20 @@ or all the steps here. !!! warning "For Notebooks" - The "Getting Started" Notebook is available [here](../../../../getting_started/getting-started-gui/getting_started.ipynb). In Taipy GUI, the process to execute a Jupyter Notebook is different from executing a Python Script. + The Notebook is available [here](../getting_started.ipynb). In Taipy GUI, + the process to execute a Jupyter Notebook is different from executing a Python Script. # Step 2: Visual elements -You can incorporate various visual elements into the basic code demonstrated in Step 1. -In this step, we will illustrate how to utilize visual elements such as charts, sliders, tables, and more within the graphical interface. +You can incorporate various visual elements into the basic code demonstrated in Step 1. In this +step, we will illustrate how to utilize visual elements such as charts, sliders, tables, and +more within the graphical interface. ## Visual elements Taipy GUI can be considered as an **augmented** Markdown; it adds the concept of -**[Visual elements](../../../../manuals/gui/viselements/index.md)** on top of all the Markdown syntax. A visual -element is a Taipy graphical object displayed on the client. It can be a +**[Visual elements](../../../../manuals/gui/viselements/index.md)** on top of all the Markdown +syntax. A visual element is a Taipy graphical object displayed on the client. It can be a [slider](../../../../manuals/gui/viselements/slider.md), a [chart](../../../../manuals/gui/viselements/chart.md), a [table](../../../../manuals/gui/viselements/table.md), an diff --git a/docs/knowledge_base/tutorials/understanding_gui/step_03/step_03.md b/docs/knowledge_base/tutorials/understanding_gui/step_03/step_03.md index 42a645fb6..0c03c3675 100644 --- a/docs/knowledge_base/tutorials/understanding_gui/step_03/step_03.md +++ b/docs/knowledge_base/tutorials/understanding_gui/step_03/step_03.md @@ -4,7 +4,8 @@ or all the steps here. !!! warning "For Notebooks" - The "Getting Started" Notebook is available [here](../../../../getting_started/getting-started-gui/getting_started.ipynb). In Taipy GUI, the process to execute a Jupyter Notebook is different from executing a Python Script. + The Notebook is available [here](../getting_started.ipynb). In Taipy GUI, + the process to execute a Jupyter Notebook is different from executing a Python Script. # Step 3: Interaction @@ -16,15 +17,22 @@ Now, the page has several visual elements: Taipy GUI manages everything in the background. -To go further with Taipy GUI, let's introduce the concept of **state**. Thanks to this state concept, Taipy natively provides multi-user GUI apps. +To go further with Taipy GUI, let's introduce the concept of **state**. Thanks to this state +concept, Taipy natively provides multi-user GUI apps. ## Multi-user - state -Try to open a few clients with the same URL. You will see that every client is independent of each other; you can change *text* on a client, and *text* will not change in other clients. This is due to the concept of **state**. +Try to open a few clients with the same URL. You will see that every client is independent of +each other; you can change *text* on a client, and *text* will not change in other clients. This +is due to the concept of **state**. -The state holds the value of all the variables used in the user interface for one specific connection. +The state holds the value of all the variables used in the user interface for one specific +connection. -For example, in the beginning, `state.text = 'Original text'`. When *text* is modified by the input (through a given graphical client), this is, in fact, *state.text* that is modified, not *text* (the global Python variable). Therefore, if you open two different clients, *text* will have two state values (*state.text*), one for each client. +For example, in the beginning, `state.text = 'Original text'`. When *text* is modified by the +input (through a given graphical client), this is, in fact, *state.text* that is modified, not +*text* (the global Python variable). Therefore, if you open two different clients, *text* will +have two state values (*state.text*), one for each client. In the code below, this concept will be used to: @@ -34,7 +42,9 @@ In the code below, this concept will be used to: ## How to connect two variables - the *[on_change()](../../../../manuals/gui/callbacks.md)* function -In *Taipy*, the `on_change()` function is a "special" function. **Taipy** will check if you created and will use a function with this name. Whenever the state of a variable is modified, the *callback* function is called with three parameters: +In *Taipy*, the `on_change()` function is a "special" function. **Taipy** will check if you +created and will use a function with this name. Whenever the state of a variable is modified, +the *callback* function is called with three parameters: - state (the state object containing all the variables); @@ -42,9 +52,13 @@ In *Taipy*, the `on_change()` function is a "special" function. **Taipy** will c - Its value. -Here, `on_change()` will be called whenever the text's value (*state.text*) changes. If a variable is changed in this function, Taipy will propagate this change automatically to the associated visual elements. +Here, `on_change()` will be called whenever the text's value (*state.text*) changes. If a +variable is changed in this function, Taipy will propagate this change automatically to the +associated visual elements. -Other callbacks specific to visual elements exist. They are named _on_change_ or _on_action_. For example, a button has an _on_action_ property. When the button is pressed, Taipy will call the function referenced in the _on_action_ property. +Other callbacks specific to visual elements exist. They are named _on_change_ or _on_action_. +For example, a button has an _on_action_ property. When the button is pressed, Taipy will call +the function referenced in the _on_action_ property. ```python from taipy.gui import Gui, notify @@ -77,4 +91,6 @@ Gui(page).run() ![Interactive GUI](result.png){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } -[_notify()_](../../../../manuals/gui/notifications.md) is a Taipy GUI function that creates a notification with text. The user can pass multiple parameters, including the _state_, the _notification_type_, and the _message_. +[_notify()_](../../../../manuals/gui/notifications.md) is a Taipy GUI function that creates a +notification with text. The user can pass multiple parameters, including the _state_, the +_notification_type_, and the _message_. diff --git a/docs/knowledge_base/tutorials/understanding_gui/step_04/step_04.md b/docs/knowledge_base/tutorials/understanding_gui/step_04/step_04.md index 162b1e913..876bd8b2f 100644 --- a/docs/knowledge_base/tutorials/understanding_gui/step_04/step_04.md +++ b/docs/knowledge_base/tutorials/understanding_gui/step_04/step_04.md @@ -4,11 +4,13 @@ or all the steps here. !!! warning "For Notebooks" - The "Getting Started" Notebook is available [here](../../../../getting_started/getting-started-gui/getting_started.ipynb). In Taipy GUI, the process to execute a Jupyter Notebook is different from executing a Python Script. + The Notebook is available [here](../getting_started.ipynb). In Taipy GUI, + the process to execute a Jupyter Notebook is different from executing a Python Script. # Step 4: Charts -Charts are an essential part of Taipy (and of any Web application!). A chart is just another visual element with many properties to customize it. +Charts are an essential part of Taipy (and of any Web application!). A chart is just another +visual element with many properties to customize it. Here is one of the simplest code to create a chart: @@ -21,10 +23,13 @@ Different formats can be passed to a chart element: a list, a Numpy array, or a ## Different useful properties -Taipy charts are based on Plotly charts. Like any other visual element, charts have a lot of parameters. +Taipy charts are based on Plotly charts. Like any other visual element, charts have a lot of +parameters. -Here are a few of the essential properties. You can also look at the [documentation](../../../../manuals/gui/viselements/chart.md) for more information. - - x and y are used to define the axis of the chart. Note that even if data inside columns are dynamic, the name of columns to display in a chart are not. +Here are a few of the essential properties. You can also look at the +[documentation](../../../../manuals/gui/viselements/chart.md) for more information. + - x and y are used to define the axis of the chart. Note that even if data inside columns are + dynamic, the name of columns to display in a chart are not. ```python data = {"x_col":[0,1,2], "y_col1":[4,1,2]} @@ -47,7 +52,10 @@ Gui("<|{data}|chart|x=x_col|y[1]=y_col_1|y[2]=y_col_2|color[1]=green|>").run() ## Different types of charts -Different types are available: maps, bar charts, pie charts, line charts, and 3D charts, ... To know how to use them quickly, types are listed [here](../../../../manuals/gui/viselements/chart.md). If compatible, two types like _scatter_, _line_, and _bar_ can also be used together on the same chart. +Different types are available: maps, bar charts, pie charts, line charts, and 3D charts, ... To +know how to use them quickly, types are listed [here](../../../../manuals/gui/viselements/chart.md). +If compatible, two types like _scatter_, _line_, and _bar_ can also be used together on the same +chart. ```python data = {"x_col":[0,1,2], "y_col_1":[4,1,2], "y_col_2":[3,1,2]} @@ -79,7 +87,8 @@ dataframe = pd.DataFrame({"Text":['Test', 'Other', 'Love'], ## Quick tip to write visual elements -To make coding easier, each visual element has a "properties" parameter where you can directly pass a Python dictionary of properties. To recreate the graph shown above, you can to the following: +To make coding easier, each visual element has a "properties" parameter where you can directly +pass a Python dictionary of properties. To recreate the graph shown above, you can to the following: ```python property_chart = {"type":"bar", diff --git a/docs/knowledge_base/tutorials/understanding_gui/step_05/step_05.md b/docs/knowledge_base/tutorials/understanding_gui/step_05/step_05.md index 406740bf4..b9f24bfd0 100644 --- a/docs/knowledge_base/tutorials/understanding_gui/step_05/step_05.md +++ b/docs/knowledge_base/tutorials/understanding_gui/step_05/step_05.md @@ -4,13 +4,18 @@ or all the steps here. !!! warning "For Notebooks" - The "Getting Started" Notebook is available [here](../../../../getting_started/getting-started-gui/getting_started.ipynb). In Taipy GUI, the process to execute a Jupyter Notebook is different from executing a Python Script. + The Notebook is available [here](../getting_started.ipynb). In Taipy GUI, + the process to execute a Jupyter Notebook is different from executing a Python Script. # Step 5: Python expression in properties -As shown before, parameters and variables in Taipy are dynamic. The same applies for every type of object, even data frames. Therefore, you can perform operations on data frames, and Taipy GUI will show real-time results on the GUI. These changes occur through the `=` assignment like `state.xxx = yyy` (`state.text = "Example"`). +As shown before, parameters and variables in Taipy are dynamic. The same applies for every type +of object, even data frames. Therefore, you can perform operations on data frames, and Taipy GUI +will show real-time results on the GUI. These changes occur through the `=` assignment like +`state.xxx = yyy` (`state.text = "Example"`). -Any expression containing `xxx` in the Markdown will propagate the changes and reload related elements. It can be simple charts or tables, but it can also be an expression like this: +Any expression containing `xxx` in the Markdown will propagate the changes and reload related +elements. It can be simple charts or tables, but it can also be an expression like this: ```python """ @@ -30,12 +35,15 @@ This kind of expression creates direct connections between visual elements witho ## A use case for NLP - Part 1 -The code for NLP is provided here, although it's not directly related to Taipy. It will come into play in Part 2 when we wrap a GUI around this NLP engine. +The code for NLP is provided here, although it's not directly related to Taipy. It will come +into play in Part 2 when we wrap a GUI around this NLP engine. Before executing this step, you should have `pip install torch` and `pip install transformers`. -The model will be downloaded and utilized in this code snippet. Note that Torch is currently only accessible for Python versions between 3.8 and 3.10. +The model will be downloaded and utilized in this code snippet. Note that Torch is currently +only accessible for Python versions between 3.8 and 3.10. -If you encounter difficulties installing these packages, you can simply provide a dictionary of random numbers as the output for the `analyze_text(text)` function. +If you encounter difficulties installing these packages, you can simply provide a dictionary of +random numbers as the output for the `analyze_text(text)` function. ```python diff --git a/docs/knowledge_base/tutorials/understanding_gui/step_06/step_06.md b/docs/knowledge_base/tutorials/understanding_gui/step_06/step_06.md index 3d7ef9dc2..ba7ff92bc 100644 --- a/docs/knowledge_base/tutorials/understanding_gui/step_06/step_06.md +++ b/docs/knowledge_base/tutorials/understanding_gui/step_06/step_06.md @@ -4,44 +4,51 @@ or all the steps here. !!! warning "For Notebooks" - The "Getting Started" Notebook is available [here](../../../../getting_started/getting_started.ipynb). In Taipy GUI, the process to execute a Jupyter Notebook is different from executing a Python Script. - It is important to check the [Notebook](../../../../getting_started/getting_started.ipynb) content and see the [documentation](../../../../manuals/gui/notebooks.md). + The Notebook is available [here](../getting_started.ipynb). In Taipy GUI, the process to + execute a Jupyter Notebook is different from executing a Python Script. + It is important to check the [Notebook](../getting_started.ipynb) + content and see the [documentation](../../../../manuals/gui/notebooks.md). # Step 6: Page layout -You've successfully built a comprehensive forecasting application capable of making predictions for multiple days -with various parameters in just a few steps. Nevertheless, there is room for substantial improvement -in the page's layout. We'll introduce three new helpful controls to enhance the page's visual appeal. -These controls are: - -- [part](../../../../manuals/gui/viselements/part.md): creates a group of text/visual elements. A useful property of `part` is _render_. If set to False, it will not display the part. This allows the developer to hide a group of visual elements dynamically. - -``` -<|part|render={bool_variable}| -Text -Or visual elements... -|> -``` - -- [layout](../../../../manuals/gui/viselements/layout.md): creates invisible columns where you can put your texts and visual elements. The _columns_ property indicates the width and number of columns. Here, we create three columns of the same width. - -``` -<|layout|columns=1 1 1| -Button in first column <|Press|button|> - -Second column - -Third column -|> -``` - -![Layout](layout.png){ width=500 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } - - -- [expandable](../../../../manuals/gui/viselements/expandable.md): creates a block that can expand or shrink. - -![expandable](expandable.png){ width=500 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } +You've successfully built a comprehensive forecasting application capable of making predictions +for multiple days with various parameters in just a few steps. Nevertheless, there is room for +substantial improvement in the page's layout. We'll introduce three new helpful controls to +enhance the page's visual appeal. These controls are: + +- [part](../../../../manuals/gui/viselements/part.md): creates a group of text/visual elements. + A useful property of `part` is _render_. If set to False, it will not display the part. This + allows the developer to hide a group of visual elements dynamically. + + ``` + <|part|render={bool_variable}| + Text + Or visual elements... + |> + ``` + +- [layout](../../../../manuals/gui/viselements/layout.md): creates invisible columns where you + can put your texts and visual elements. The _columns_ property indicates the width and number + of columns. Here, we create three columns of the same width. + + ``` + <|layout|columns=1 1 1| + Button in first column <|Press|button|> + + Second column + + Third column + |> + ``` + + ![Layout](layout.png){ width=500 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } + + +- [expandable](../../../../manuals/gui/viselements/expandable.md): creates a block that can + expand or shrink. + + ![expandable](expandable.png){ width=500 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } ## Back to the code diff --git a/docs/knowledge_base/tutorials/understanding_gui/step_07/step_07.md b/docs/knowledge_base/tutorials/understanding_gui/step_07/step_07.md index fbe58f80f..1baebfdc3 100644 --- a/docs/knowledge_base/tutorials/understanding_gui/step_07/step_07.md +++ b/docs/knowledge_base/tutorials/understanding_gui/step_07/step_07.md @@ -4,14 +4,16 @@ or all the steps here. !!! warning "For Notebooks" - The "Getting Started" Notebook is available [here](../../../../getting_started/getting-started-gui/getting_started.ipynb). In Taipy GUI, the process to execute a Jupyter Notebook is different from executing a Python Script. + The "Getting Started" Notebook is available [here](../getting_started.ipynb). In Taipy GUI, + the process to execute a Jupyter Notebook is different from executing a Python Script. # Step 7: Multi-pages, navbars, and menus -Taipy significantly simplifies the process of building a multi-page application. To create a multi-page application, -you need to define a dictionary of pages. In this example, we will create three Pages: -a Root page and two additional pages (page 1 & page 2). We will incorporate Visual elements, -such as a menu or navbar, on the Root page to facilitate navigation between page 1 and page 2. +Taipy significantly simplifies the process of building a multi-page application. To create a +multi-page application, you need to define a dictionary of pages. In this example, we will +create three Pages: a Root page and two additional pages (page 1 & page 2). We will incorporate +Visual elements, such as a menu or navbar, on the Root page to facilitate navigation between +page 1 and page 2. ```python @@ -35,9 +37,11 @@ Gui(pages=pages).run() ## Navigating between pages -- [menu](../../../../manuals/gui/viselements/menu.md): creates a menu on the left to navigate through the pages. +- [menu](../../../../manuals/gui/viselements/menu.md): creates a menu on the left to navigate + through the pages. -`<|menu|label=Menu|lov={lov_pages}|on_action=on_menu|>`. For example, this code creates a menu with two pages: + `<|menu|label=Menu|lov={lov_pages}|on_action=on_menu|>`. For example, this code creates a menu + with two pages: ```python from taipy.gui import Gui, navigate @@ -64,7 +68,8 @@ Gui(pages=pages).run() ![Menu](menu.png){ width=500 style="margin:auto;display:block" } -- [navbar](../../../../manuals/gui/viselements/navbar.md): creates an element to navigate through the Taipy pages by default +- [navbar](../../../../manuals/gui/viselements/navbar.md): creates an element to navigate + through the Taipy pages by default ```python from taipy.gui import Gui @@ -88,7 +93,7 @@ Gui(pages=pages).run() ## Back to the code -The Markdown created in our previous steps will be the first page (named _page_) of the application. +The Markdown created in our previous steps will be the first page (named _page_) of the application. ![Previous Markdown](first_markdown.png){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } @@ -132,7 +137,8 @@ def analyze_file(state): state.path = None ``` -This little code below assembles our previous page and this new page. The _navbar_ in the root page is also visible on both pages allowing for easy switching between pages. +This little code below assembles our previous page and this new page. The _navbar_ in the root +page is also visible on both pages allowing for easy switching between pages. ```python @@ -146,4 +152,4 @@ pages = {"/":"<|toggle|theme|>\n
\n<|navbar|>\n
", Gui(pages=pages).run() ``` -![Multi Pages](result.png){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } +![Multi-Pages](result.png){ width=700 style="margin:auto;display:block;border: 4px solid rgb(210,210,210);border-radius:7px" } diff --git a/docs/manuals/auth/authentication.md b/docs/manuals/auth/authentication.md index 30ff39f04..785e6614e 100644 --- a/docs/manuals/auth/authentication.md +++ b/docs/manuals/auth/authentication.md @@ -41,7 +41,7 @@ Taipy Enterprise edition supports three authentication protocols: See the [LDAP Authenticator](#ldap-authenticator) below for more information. -!!! Note "Default authenticator" +!!! note "Default authenticator" Most applications will use a single authenticator. This authenticator is called the *default authenticator* and is created automatically when `login()^` is called for the first time or when any `Authenticator^` for any protocol is created, @@ -57,15 +57,16 @@ Taipy Enterprise edition supports three authentication protocols: To summarize: - The first `Authenticator^` that is created becomes the application's - default authenticator. + default authenticator. - When `login()^` is called: - - A default authenticator is created if there is none, based on the authentication configuration. + - A default authenticator is created if there is none, based on the authentication + configuration. - If Taipy could not find the configuration allowing to create such a default - authenticator, a *None* authenticator is created and set as the default - authenticator. + authenticator, a *None* authenticator is created and set as the default + authenticator. - The default authenticator's `(Authenticator.)login()^` function is invoked - with the arguments that were provided to `login()^`. + with the arguments that were provided to `login()^`. Beside their specific parameters, all authenticators have two parameters that you @@ -91,8 +92,9 @@ are provided. To create a *None* authenticator, you can instantiate an `Authenticator^` object setting the *protocol* argument of the constructor to "none". -!!! Note "Using Taipy configuration to set default authenticator" - To set the *default authenticator* to `none` you can use the authentication configuration either in Python or TOML: +!!! note "Using Taipy configuration to set default authenticator" + To set the *default authenticator* to `none` you can use the authentication configuration + either in Python or TOML: === "Python configuration" @@ -120,9 +122,8 @@ The Taipy Authenticator is an internal authenticator originally designed for testing purposes, so an application can test authentication and authorization features without having to install and deploy a real authentication server. -A Taipy Authenticator is created by the -[`Authenticator` constructor](Authenticator.__init__()^) when invoked with the -*protocol* argument set to "taipy". +A Taipy Authenticator is created by the [`Authenticator` constructor](Authenticator.__init__()^) +when invoked with the *protocol* argument set to "taipy". You can set the *roles*' argument to a dictionary that associates a set of role names to every username you want to grant login access to.
@@ -147,9 +148,9 @@ to the username when calling `Authenticator.login()^`: - `authenticator.login("user1", "anything_else")` will raise the `InvalidCredentials^` exception, rejecting the login attempt. -!!! Note "Using Taipy configuration to set default authenticator" - To set the *default authenticator* to a Taipy authenticator with roles, you can use the authentication - configuration either in Python or Toml: +!!! note "Using Taipy configuration to set default authenticator" + To set the *default authenticator* to a Taipy authenticator with roles, you can use the + authentication configuration either in Python or Toml: === "Python configuration" @@ -183,16 +184,14 @@ to the username when calling `Authenticator.login()^`: ``` ### Password-protected authentication -The Taipy Authenticator can password-protect the creation of credentials, -using the *passwords*' argument of the -[`Authenticator` constructor](Authenticator.__init__()^). This argument expects a -dictionary that associates a username with a password. However, in order not to -expose these passwords, the password values need to be hashed before they are given -to the application (in the `Authenticator^` constructor -- using the *passwords* -or in the authentication configuration).
-In the *passwords* argument, the dictionary actually associates a username -with a hashed value for the password. See the [section below](#creating-hashed-passwords) -to learn how to create hashed password values. +The Taipy Authenticator can password-protect the creation of credentials, using the *passwords*' +argument of the [`Authenticator` constructor](Authenticator.__init__()^). This argument expects +a dictionary that associates a username with a password. However, in order not to expose these +passwords, the password values need to be hashed before they are given to the application (in the +`Authenticator^` constructor -- using the *passwords* or in the authentication configuration).
+In the *passwords* argument, the dictionary actually associates a username with a hashed value +for the password. See the [section below](#creating-hashed-passwords) to learn how to create +hashed password values. You can indicate what are the declared users' passwords: ``` @@ -206,12 +205,13 @@ authenticator = Authenticator("taipy", passwords=passwords) Note that these values are the one resulting from the example of the [creating hashed passwords](#creating-hashed-passwords) section below. -Calling `login("user1", "pass123")^` will result in a valid `Credentials^` -instance where the assigned roles is an empty set. +Calling `login("user1", "pass123")^` will result in a valid `Credentials^` instance where the +assigned roles is an empty set. -!!! Note "Using Taipy configuration to set default authenticator" - To set the *default authenticator* to a Taipy authenticator with passwords, you can use the authentication - configuration either in Python or Toml: +!!! note "Using Taipy configuration to set default authenticator" + + To set the *default authenticator* to a Taipy authenticator with passwords, you can use the + authentication configuration either in Python or Toml: === "Python configuration" @@ -242,10 +242,9 @@ instance where the assigned roles is an empty set. taipy.auth.login("user1", "anything_else") # raise an InvalidCredentials exception ``` -Of course, you can combine both roles and password for any given user, using -both the *roles* and *passwords* arguments of the -[`Authenticator` constructor](Authenticator.__init__()^), or using its -*config* argument: +Of course, you can combine both roles and password for any given user, using both the *roles* +and *passwords* arguments of the [`Authenticator` constructor](Authenticator.__init__()^), or +using its *config* argument: ``` users={ "roles": { @@ -277,12 +276,13 @@ user2 - Logged in. Roles={'role2', 'TAIPY_ADMIN'} user3 - Logged in. Roles={'role1', 'role2', 'TAIPY_ADMIN'} ``` -Note that, because "user3" was not constrained by any password, we need -to use the username as the password value for this user. +Note that, because "user3" was not constrained by any password, we need to use the username as +the password value for this user. -!!! Note "Using Taipy configuration to set default authenticator" - To set the *default authenticator* to a Taipy authenticator with roles and passwords, you can use the authentication - configuration either in Python or Toml: +!!! note "Using Taipy configuration to set default authenticator" + + To set the *default authenticator* to a Taipy authenticator with roles and passwords, you + can use the authentication configuration either in Python or Toml: === "Python configuration" @@ -325,35 +325,32 @@ to use the username as the password value for this user. ### Creating hashed passwords -Taipy provides two ways of creating a hashed password provided the plain text -representation of the password: +Taipy provides two ways of creating a hashed password provided the plain text representation of +the password: - - API: You can use function `hash_taipy_password()^` that, given a plain - text string, returns the hashed value for it. +- API: You can use function `hash_taipy_password()^` that, given a plain text string, returns + the hashed value for it. - - CLI: The `taipy.auth` module has an entry point that can be invoked from - the CLI, using the `-m` option of Python, and the `-p` option of the - `taipy.auth` module. Below is an example of how to use the CLI option. +- CLI: The `taipy.auth` module has an entry point that can be invoked from + the CLI, using the `-m` option of Python, and the `-p` option of the + `taipy.auth` module. Below is an example of how to use the CLI option. -Note that only the first 16 characters of the plain text password are -used when creating the hashed password. +Note that only the first 16 characters of the plain text password are used when creating the +hashed password. -Before you use any of these two ways for creating hashed passwords, you must come -up with a secret hash value. This value is used to generate unique hashed passwords. -This value must be set to the 'TAIPY_AUTH_HASH' environment variable in -order to generate hashed passwords, as well as when running the application, -so passwords can be verified.
+Before you use any of these two ways for creating hashed passwords, you must come up with a +secret hash value. This value is used to generate unique hashed passwords. This value must be +set to the 'TAIPY_AUTH_HASH' environment variable in order to generate hashed passwords, as well +as when running the application, so passwords can be verified.
The value of 'TAIPY_AUTH_HASH' can be any string value.
-The value of 'TAIPY_AUTH_HASH' **must** be the same when generating the -hashed passwords and when running the application that invokes the `login()^` -function. +The value of 'TAIPY_AUTH_HASH' **must** be the same when generating the hashed passwords and +when running the application that invokes the `login()^` function. !!! example "Create a hashed password using the API" - Here is an example of how you can create a hashed password using - the Taipy API. + + Here is an example of how you can create a hashed password using the Taipy API. - We assume that the environment variable 'TAIPY_AUTH_HASH' is set - to "Taipy". + We assume that the environment variable 'TAIPY_AUTH_HASH' is set to "Taipy". ``` from taipy.auth import hash_taipy_password @@ -372,11 +369,10 @@ function. ``` !!! example "Create a hashed password using the CLI" - Here is an example of how you can create hashed passwords using - the Taipy CLI. - Here again, we assume that the environment variable 'TAIPY_AUTH_HASH' is - set to "Taipy". + Here is an example of how you can create hashed passwords using the Taipy CLI. + + Here again, we assume that the environment variable 'TAIPY_AUTH_HASH' is set to "Taipy". ``` $ python -m taipy.auth -p pass123 pass1234 @@ -387,31 +383,32 @@ function. hash(pass1234)=JQlZ4IXorPcJYvMLFWE/Gu52XNfavMe ``` - Note that the hashed values are the same as in the first example. This is - entirely due to the fact that we have used the same secret hashing value - in 'TAIPY_AUTH_HASH'. + Note that the hashed values are the same as in the first example. This is entirely due to + the fact that we have used the same secret hashing value in 'TAIPY_AUTH_HASH'. ## LDAP Authenticator Taipy also provide support for LDAP authentication. -The LDAP authenticator has two specific parameters that need to be provided in order -to properly connect to the directory service: +The LDAP authenticator has two specific parameters that need to be provided in order to properly +connect to the directory service: - *server*: the URL of the LDAP server that we want to connect to.
- If you are using the Taipy configuration, the value for this argument - is retrieved if needed from _**Config.authentication_config.server**_. + If you are using the Taipy configuration, the value for this argument + is retrieved if needed from _**Config.authentication_config.server**_. - *base_dn*: the base distinguished name for that LDAP server.
- If you are using the Taipy configuration, the value for this argument - is retrieved if needed from _**Config.authentication_config.base_dn**_. + If you are using the Taipy configuration, the value for this argument + is retrieved if needed from _**Config.authentication_config.base_dn**_. -!!! important "LDAP server support" - Using the LDAP authentication protocol assumes that an LDAP server is set up. - Taipy provides no support for setting up the server. +!!! note "LDAP server support" + + Using the LDAP authentication protocol assumes that an LDAP server is set up. Taipy provides + no support for setting up the server. -!!! Note "Using Taipy configuration to set default authenticator" - To set the *default authenticator* to an LDAP authenticator you can use the authentication configuration either in - Python or Toml: +!!! note "Using Taipy configuration to set default authenticator" + + To set the *default authenticator* to an LDAP authenticator you can use the authentication + configuration either in Python or Toml: === "Python configuration" diff --git a/docs/manuals/auth/authorization.md b/docs/manuals/auth/authorization.md index 2a5a4d353..5aeb3f0bd 100644 --- a/docs/manuals/auth/authorization.md +++ b/docs/manuals/auth/authorization.md @@ -201,7 +201,8 @@ user can display. The `AuthorizedPage^` class lets you specify a role traits filter where both the *success* and *failure* cases must be a page renderer (whether a `Markdown^` or an `Html^` instance - see the -[section on Page Renderers](../gui/pages.md#defining-the-page-content) for more information).
+[section on Page Renderers](../gui/pages/index.md#defining-the-page-content) for more +information).
Instead of calling `Gui.add_page()` for the page renderer, you will use the same API, providing the defined `AuthorizedPage^` instance.
When the requested page is an `AuthorizedPage^`, the role traits filter is triggered so that the diff --git a/docs/manuals/cli/create.md b/docs/manuals/cli/create.md index db8964d2b..1406ee47e 100644 --- a/docs/manuals/cli/create.md +++ b/docs/manuals/cli/create.md @@ -18,29 +18,30 @@ Does the application use Rest API? [No]: $ cd ./new_application $ taipy run app.py ``` -In this example, we scaffold a new application using the default Taipy template, which lets us create a simple, -minimalized Taipy application. +In this example, we scaffold a new application using the default Taipy template, which lets us +create a simple, minimal Taipy application. -!!! Info +!!! info - In the prompt, we can see the question and the default value in the square brackets. - We can provide an answer or press enter to use the default value. + In the prompt, we can see the question and the default value in the square brackets. + We can provide an answer or press enter to use the default value. - The first question defines the application root folder as "new_application" -- In the second and third questions, we set the main Python file of the application as "app.py" and the web page's title - as "App Title". -- In the 4th question, we clarify that we want a Taipy multi-page GUI application with three pages, and the page names - are "slide_1", "slide_2", and "slide_3". If there is no answer to this question, the application will be a single page - application. Please note that the names must be valid Python identifiers. -- In the 5th question, we clarify that we want to use scenario management, so the application should include the - Taipy Core service. -- In the 6th question, we chose the default answer is No, meaning we don't want to use Rest API, so the - application should not include the Taipy Rest API service. - -Finally, we changed the directory (`cd`) to our newly created folder and started the application by running -`taipy run app.py`. +- In the second and third questions, we set the main Python file of the application as "app.py" + and the web page's title as "App Title". +- In the 4th question, we clarify that we want a Taipy multi-page GUI application with three + pages, and the page names are "slide_1", "slide_2", and "slide_3". If there is no answer to + this question, the application will be a single page application. Please note that the names + must be valid Python identifiers. +- In the 5th question, we clarify that we want to use scenario management, so the application + should include the Taipy Core service. +- In the 6th question, we chose the default answer is No, meaning we don't want to use Rest API, + so the application should not include the Taipy Rest API service. + +Finally, we changed the directory (`cd`) to our newly created folder and started the application +by running `taipy run app.py`. ## From a specific template @@ -56,16 +57,17 @@ $ cd ./new_application $ taipy run app.py ``` -In this example, we scaffold a new Taipy application using the "scenario-management" template, which utilizes -[a scenario selector](./../gui/corelements/scenario_selector.md) to allow creating, managing, and running scenarios -directly from the GUI page. +In this example, we scaffold a new Taipy application using the "scenario-management" template, +which utilizes [a scenario selector](./../gui/corelements/scenario_selector.md) to allow +creating, managing, and running scenarios directly from the GUI page. Please refer to the next section for a list of templates. ## List of templates -You can see the list of supported templates by running `taipy help create` command. Alternatively, you can -use the *--help* or *-h* options by running `taipy create --help` or `taipy create -h`. +You can see the list of supported templates by running `taipy help create` command. +Alternatively, you can use the *--help* or *-h* options by running `taipy create --help` or +`taipy create -h`. ```console $ taipy help create diff --git a/docs/manuals/cli/index.md b/docs/manuals/cli/index.md index 03b865971..1c04a1d86 100644 --- a/docs/manuals/cli/index.md +++ b/docs/manuals/cli/index.md @@ -4,19 +4,19 @@ Installing Taipy gives you access to the `taipy` command-line interface (CLI), w commands to streamline your web application development. Here is a list of available commands: -- [:material-arrow-right: taipy help](help.md): This command displays the comprehensive help menu, providing essential - information about each available command and its usage. +- [:material-arrow-right: taipy help](help.md): This command displays the comprehensive help + menu, providing essential information about each available command and its usage. -- [:material-arrow-right: taipy create](create.md): With this command, you can easily initiate a new Taipy - application by utilizing a template as a starting point for your project. +- [:material-arrow-right: taipy create](create.md): With this command, you can easily initiate a + new Taipy application by utilizing a template as a starting point for your project. - [:material-arrow-right: taipy run](run.md): This command allows you to run your Taipy application. -- [:material-arrow-right: taipy manage-versions](manage-versions.md): This command empowers you to efficiently - manage the versions of your user application and their related data. +- [:material-arrow-right: taipy manage-versions](manage-versions.md): This command empowers you + to efficiently manage the versions of your user application and their related data. -- [:material-arrow-right: taipy version](version.md): Obtain the installed Taipy version using this command to keep - track of the Taipy library's current release. +- [:material-arrow-right: taipy version](version.md): Obtain the installed Taipy version using + this command to keep track of the Taipy library's current release. -- [:material-arrow-right: taipy migrate](migrate.md): This command allows users of Taipy -`version 2.x` to migrate their Taipy entities to `version 3.0` when upgrading Taipy version. +- [:material-arrow-right: taipy migrate](migrate-entities.md): This command allows users of Taipy + `version 2.x` to migrate their Taipy entities to `version 3.0` when upgrading Taipy version. diff --git a/docs/manuals/cli/manage-versions.md b/docs/manuals/cli/manage-versions.md index 515f473c5..632cbe618 100644 --- a/docs/manuals/cli/manage-versions.md +++ b/docs/manuals/cli/manage-versions.md @@ -25,9 +25,9 @@ Below is the list of all the optional arguments: ## List capabilities with the --help option -To display the help message of the `manage-version` command, you can run `taipy help manage-versions` command. -Alternatively, you can use the *--help* or *-h* options by running `taipy manage-versions --help` -or `taipy manage-versions -h`. +To display the help message of the `manage-version` command, you can run +`taipy help manage-versions` command. Alternatively, you can use the *--help* or *-h* options by +running `taipy manage-versions --help` or `taipy manage-versions -h`. ```console $ taipy help manage-versions @@ -64,7 +64,8 @@ d74ec95e-6b98-4612-b50b-d171599fa3e9 Development (latest) 2023-01-19 14:45:1 In the example above, there are 5 versions of the application: -- The development version "d74ec95e-6b98-4612-b50b-d171599fa3e9" which is also the latest version used. +- The development version "d74ec95e-6b98-4612-b50b-d171599fa3e9" which is also the latest + version used. - Two experiment versions "7a24dbb8-bdf6-4c84-9ddf-7b921abc5df9" and "3.0". - Two production versions "1.0" and "2.0". @@ -89,7 +90,7 @@ d74ec95e-6b98-4612-b50b-d171599fa3e9 Development (latest) 2023-01-19 14:45:1 1.0 Experiment 2023-01-12 09:10:35 ``` -!!! Warning +!!! warning You can not use an existing version as the new version name, since it may cause different versions to overlap each other. diff --git a/docs/manuals/cli/migrate-entities.md b/docs/manuals/cli/migrate-entities.md index e5d3cfadd..f247e1cfd 100644 --- a/docs/manuals/cli/migrate-entities.md +++ b/docs/manuals/cli/migrate-entities.md @@ -1,29 +1,31 @@ # Migrate entities from earlier versions to Taipy 3.0 Taipy 3.0 provides a CLI option to update entities from older Taipy versions to `3.0`. It -is recommended to update the Taipy application code to Taipy 3.0 before executing the -entities migration. +is recommended to update the Taipy application code to Taipy 3.0 before executing the entity +migration. -!!! important "Supported Taipy versions" +!!! note "Supported Taipy versions" The migration supports **Taipy 2.0** or newer. ## Migration arguments -The migrate CLI has one argument, `--repository-type` that accepts 3 values: `filesystem`, -`sql`, and `mongo`. Each repository type must be succeeded of additional arguments, as -decribed below: +The 'migrate' CLI has one argument, `--repository-type` that accepts 3 values: `filesystem`, +`sql`, and `mongo`. Each repository type must be succeeded of additional arguments, as described +below: - *filesystem* must be succeeded by the path to the filesystem folder that holds your Taipy -application data. It corresponds to the `storage_folder` attribute in the configuration `CORE` -section. If it has not been changed explicitly the value is `.data` inside the application root -directory if it has not been provided explicitly. + application data. It corresponds to the `storage_folder` attribute in the configuration `CORE` + section. If it has not been changed explicitly the value is `.data` inside the application root + directory if it has not been provided explicitly. - *sql* must be succeeded by the path to the sqlite file that holds your Taipy Application data. - *mongo* must be succeeded by the credentials to access the mongo database that holds -your Taipy Application data. The credentials must follow the order: `host`, `port`, `username`, and `password`. + your Taipy Application data. The credentials must follow the order: `host`, `port`, `username`, + and `password`. To display the help section of `taipy migrate` CLI, you can run the `taipy help migrate` command. -Alternatively, you can use the *--help* or *-h* options by running `taipy migrate --help` or `taipy migrate -h`. +Alternatively, you can use the *--help* or *-h* options by running `taipy migrate --help` or +`taipy migrate -h`. ```console $ taipy help migrate @@ -36,7 +38,8 @@ optional arguments: case of mongo host, port, user and password must be informed, if left empty it is assumed default values ``` -To migrate the entities of an Taipy application with a filesystem repository. We can run the following command: +To migrate the entities of a Taipy application with a filesystem repository. We can run the +following command: ```console $ taipy migrate --repository-type filesystem .data @@ -44,7 +47,8 @@ $ taipy migrate --repository-type filesystem .data Where `.data` is the path to the directory that holds the Taipy application data. -To migrate the entities of an Taipy application with a sqlite repository. We can run the following command: +To migrate the entities of a Taipy application with a sqlite repository. We can run the +following command: ```console $ taipy migrate --repository-type filesystem ~/taipy.sqlite3 @@ -52,13 +56,15 @@ $ taipy migrate --repository-type filesystem ~/taipy.sqlite3 Where `~/taipy.sqlite3` is the path to the sqlite file that holds the Taipy application data. -To migrate the entities of an Taipy application with a sqlite repository. We can run the following command: +To migrate the entities of a Taipy application with a sqlite repository. We can run the +following command: ```console $ taipy migrate --repository-type mongo localhost 27017 username password ``` -Where the arguments are the credentials to access the mongo database that holds the Taipy application data. +Where the arguments are the credentials to access the mongo database that holds the Taipy +application data. !!! info diff --git a/docs/manuals/cli/run.md b/docs/manuals/cli/run.md index 812275ff6..d23fe0bab 100644 --- a/docs/manuals/cli/run.md +++ b/docs/manuals/cli/run.md @@ -7,27 +7,30 @@ To start the Taipy application, you can run: $ taipy run main.py ``` -!!! note "Using the 'python' command" +??? note "Using the 'python' command" - An alternative way to run your application is to use the `python` command, which runs the Python interpreter. + An alternative way to run your application is to use the `python` command, which runs the + Python interpreter. ```console $ python main.py ``` - However, when working with command-line arguments, Taipy arguments can be confused with arguments - of other libraries or your application's arguments. To avoid this confusion, we recommend - using the `taipy run` command, which is more robust in avoiding any command-line argument conflict. + However, when working with command-line arguments, Taipy arguments can be confused with + arguments of other libraries or your application's arguments. To avoid this confusion, we + recommend using the `taipy run` command, which is more robust in avoiding any command-line + argument conflict. ## With Taipy arguments -Taipy CLI will parse internal arguments (interpreted by Taipy) and pass the others to your Taipy application. -For specific descriptions and usages of each argument, refer to: +Taipy CLI will parse internal arguments (interpreted by Taipy) and pass the others to your Taipy +application. For specific descriptions and usages of each argument, refer to: - [Configuring the `Gui` instance](../gui/configuration.md#configuring-the-gui-instance) -- [Configuring version management system using the CLI](../core/versioning/configuration.md#configure-using-the-cli) +- [Configuring version management using the CLI](../core/versioning/configuration.md#configure-using-the-cli) To display the list of available Taipy arguments, you can run the `taipy help run` command. -Alternatively, you can use the *--help* or *-h* options by running `taipy run --help` or `taipy run -h`. +Alternatively, you can use the *--help* or *-h* options by running `taipy run --help` or +`taipy run -h`. ```console $ taipy help run @@ -118,6 +121,6 @@ to your application. $ taipy run main.py --port 8080 external-args --host data.server.com --port 2714 --debug ``` -In this example, your Taipy application will be started on *localhost:8080* with *debug* off since we -do not specify *--debug* parameter for Taipy. Meanwhile, your application will run with *--debug* -parameter and read data from *data.server.com:2714*. +In this example, your Taipy application will be started on *localhost:8080* with *debug* off +since we do not specify *--debug* parameter for Taipy. Meanwhile, your application will run with +*--debug* parameter and read data from *data.server.com:2714*. diff --git a/docs/manuals/cli/version.md b/docs/manuals/cli/version.md index 58c03959a..4cb62f2e3 100644 --- a/docs/manuals/cli/version.md +++ b/docs/manuals/cli/version.md @@ -1,6 +1,6 @@ # Get Taipy version -You can check your current installed version of Taipy by running the `taipy --version` (or `taipy -v`) -command in a terminal (Linux, macOS) or command prompt (Windows). +You can check your current installed version of Taipy by running the `taipy --version` (or +`taipy -v`) command in a terminal (Linux, macOS) or command prompt (Windows). ```console $ taipy --version @@ -8,4 +8,4 @@ Taipy 2.3.0 ``` If you don't see a supported version of Taipy, you'll need to either upgrade Taipy or perform a -fresh install, as described in the [Installation page](../../installation.md). +fresh install, as described in the [Installation page](../../installation/index.md). diff --git a/docs/manuals/core/basic_examples/index.md b/docs/manuals/core/basic_examples/index.md index d818f904f..7334dc651 100644 --- a/docs/manuals/core/basic_examples/index.md +++ b/docs/manuals/core/basic_examples/index.md @@ -98,10 +98,9 @@ to the function `build_message()` and writes the result in the output data node. Line 6 reads and prints the output data node *message* that has been written by the execution of the scenario `zinedine_scenario`. -In line 8, we use the same scenario configuration to instantiate a second scenario: `kylian_scenario`. -Similarly, in lines 9-11, we write some value in its input data node, submit it and print the result written -in its output data node. - +In line 8, we use the same scenario configuration to instantiate a second scenario: +`kylian_scenario`. Similarly, in lines 9-11, we write some value in its input data node, submit +it and print the result written in its output data node. Here is the complete python code corresponding to the example: `basic_example.py` @@ -118,16 +117,17 @@ Hello Kylian Mbappe! !!! note This third step consists in calling the various Core APIs to access, manage and submit the Taipy - entities. Typically it is implemented in Python functions that are called by a graphical interface - built with [Taipy GUI](../../gui/index.md). + entities. Typically it is implemented in Python functions that are called by a graphical + interface built with [Taipy GUI](../../gui/index.md). For example, the `tp.create_scenario()` or the `tp.submit()` - methods are called when clicking respectively on a "create scenario" or "submit scenario" buttons. - When displaying a data node in a graphical component (chart, table, etc. ) the `read()` and `write()` - method are called to edit and retrieve the data. + methods are called when clicking respectively on a "create scenario" or "submit scenario" + buttons. When displaying a data node in a graphical component (chart, table, etc. ) the + `read()` and `write()` method are called to edit and retrieve the data. -!!! important +!!! note - Please refer to the [Getting started with Core](../../../getting_started/getting-started-core/index.md) - manual for a more realistic use case. + Please refer to the + [Scenario management](../../../knowledge_base/tutorials/scenario_management_overview/index.md) + tutorial for a more realistic use case. diff --git a/docs/manuals/core/concepts/data-node.md b/docs/manuals/core/concepts/data-node.md index eed4588d8..86b9db1bf 100644 --- a/docs/manuals/core/concepts/data-node.md +++ b/docs/manuals/core/concepts/data-node.md @@ -36,7 +36,7 @@ path to the file and the Python class used to represent a CSV line. history**_, the _**trained model**_, the _**current month**_, the _**sales predictions**_, the production _**capacity**_, and the _**production orders**_. -!!! Note +!!! note Taipy proposes various predefined _data nodes_ corresponding to the most popular _storage types_. More details on the [Data node configuration page](../config/data-node-config.md) diff --git a/docs/manuals/core/concepts/execution-flow.md b/docs/manuals/core/concepts/execution-flow.md index 4b03a22a0..2b732b535 100644 --- a/docs/manuals/core/concepts/execution-flow.md +++ b/docs/manuals/core/concepts/execution-flow.md @@ -1,6 +1,6 @@ # Execution flow -!!! important "Reminder: Config vs Entities" +!!! note "Reminder: Config vs Entities" The **data nodes**, **tasks**, and **scenarios** concepts have two types of Taipy objects related to them: **configurations** and runtime **entities**. **Sequences** also has its configuration object that is provided through diff --git a/docs/manuals/core/concepts/index.md b/docs/manuals/core/concepts/index.md index 012d16276..1dc409ce4 100644 --- a/docs/manuals/core/concepts/index.md +++ b/docs/manuals/core/concepts/index.md @@ -56,7 +56,7 @@ This section aims at defining the following Taipy Core concepts. - A [Scope](scope.md) represents the _visibility_ of a data node in the graph of entities, and the level of its owner (Scenario, Cycle, Global). -!!! important "Definition: Config vs Entities" +!!! note "Definition: Config vs Entities" Among the concepts described in this section, **data nodes**, **tasks**, and **scenarios** have two types of Taipy objects related to them: _configuration_ objects and _runtime_ objects. diff --git a/docs/manuals/core/concepts/task.md b/docs/manuals/core/concepts/task.md index 558374656..3cb055938 100644 --- a/docs/manuals/core/concepts/task.md +++ b/docs/manuals/core/concepts/task.md @@ -27,7 +27,7 @@ the task configuration `TaskConfig^` that must be provided when instantiating a predictions**_ as input data nodes and returns the _**production orders**_ as output. -!!! Important +!!! note The data nodes _sales history_, _current month_, and _capacity_ are considered as **input** data nodes since no task computes them.
The _trained model_ and _sales predictions_' data nodes are considered as **intermediate** data nodes while diff --git a/docs/manuals/core/config/advanced-config.md b/docs/manuals/core/config/advanced-config.md index 679d563a8..8ffff0886 100644 --- a/docs/manuals/core/config/advanced-config.md +++ b/docs/manuals/core/config/advanced-config.md @@ -36,7 +36,7 @@ code. This configuration can be done using methods from the `Config^` class. Thi be used during the application development phase. It overrides the default configuration: the default configuration applies if some values are not provided. -!!! Example "Design of the application to configure" +!!! example "Design of the application to configure" ![scenarios](../pic/scenarios.svg){ align=left } diff --git a/docs/manuals/core/config/core-config.md b/docs/manuals/core/config/core-config.md index 2930bc67e..f8c6cae71 100644 --- a/docs/manuals/core/config/core-config.md +++ b/docs/manuals/core/config/core-config.md @@ -2,28 +2,36 @@ The `CoreSection^` holds configuration fields related to the Core service. Here are the (optional) configurable properties: -- _**root_folder**_: The path of the base folder for the Taipy application, its default value is "./taipy/". -- _**storage_folder**_: The folder name used to store Taipy data, its default value is ".data/". It is used in - conjunction with the root_folder field. That means the default storage path is "./taipy/.data/". +- _**root_folder**_: The path of the base folder for the Taipy application, its default value is + "./taipy/". +- _**storage_folder**_: The folder name used to store Taipy data, its default value is ".data/". + It is used in conjunction with the root_folder field. That means the default storage path is + "./taipy/.data/". - _**read_entity_retry**_: An integer number only used with `filesystem` _**repository_type**_.
-It corresponds to the number of times Taipy retries reading an entity after a failed attempt for concurrent access.
-The default value is 1. -- _**repository_type**_: The type of storage that will be used to hold Taipy entities. Available options are: - `filesystem`, `sql` and `mongo`. The filesystem will be used as the default repository if no repository type is informed. -- _**repository_properties**_: A dictionary of properties that will be used to instantiate the chosen repository. - Only required if the chosen repository is `sql` or `mongo`.
- If _**repository_type**_ is set to `filesystem`, Taipy uses _**root_folder**_ and _**storage_folder**_ to store - entities. In this case, _**repository_properties**_ attribute is not required.
- If _**repository_type**_ is set to `sql`, the _**db_location**_ attribute is required as the path of a sqlite3 - database file. Please refer to [SQL storage section](core-config.md#sql-storage-for-taipy-entities).
- If _**repository_type**_ is set to `mongo`, the possible properties are _**mongodb_hostname**_, _**mongodb_user**_, - _**mongodb_password**_, _**mongodb_port**_, _**application_db**_, _**properties**_. Please refer to - [MongoDB storage section](core-config.md#mongodb-storage-for-taipy-entities). + It corresponds to the number of times Taipy retries reading an entity after a failed attempt + for concurrent access.
+ The default value is 1. +- _**repository_type**_: The type of storage that will be used to hold Taipy entities. Available + options are: `filesystem`, `sql` and `mongo`. The filesystem will be used as the default + repository if no repository type is informed. +- _**repository_properties**_: A dictionary of properties that will be used to instantiate the + chosen repository. Only required if the chosen repository is `sql` or `mongo`.
+ If _**repository_type**_ is set to `filesystem`, Taipy uses _**root_folder**_ and + _**storage_folder**_ to store entities. In this case, _**repository_properties**_ attribute + is not required.
+ If _**repository_type**_ is set to `sql`, the _**db_location**_ attribute is required as the + path of a sqlite3 database file. Please refer to + [SQL storage section](core-config.md#sql-storage-for-taipy-entities).
+ If _**repository_type**_ is set to `mongo`, the possible properties are + _**mongodb_hostname**_, _**mongodb_user**_, _**mongodb_password**_, _**mongodb_port**_, + _**application_db**_, _**properties**_. Please refer to + [MongoDB storage section](core-config.md#mongodb-storage-for-taipy-entities). - _**mode**_: A string that indicates the mode of the version management system. - Possible values are *"development"*, *"experiment"*, or *"production"*. -- _**version_number**_: The identifier of the version. In development mode, the version number is ignored. -- _**force**_: Indicates whether Taipy will override a version even if the configuration has changed - or not and run the application. Default to False. + Possible values are *"development"*, *"experiment"*, or *"production"*. +- _**version_number**_: The identifier of the version. In development mode, the version number + is ignored. +- _**force**_: Indicates whether Taipy will override a version even if the configuration has + changed or not and run the application. Default to False. === "Python configuration" @@ -64,15 +72,17 @@ The default value is 1. In this example, we configure: - Custom values for the *root_folder*, *storage_folder*, and *read_entity_retry* parameters. - Note that most of the time, the default values can be used. - - The *mode* of the version management system to experiment mode, and the *version_number* is set to "1.0.0".
- Please refer to the [Version management configuration](./manuals/core/versioning/configuration.md) - documentation page for more details. + Note that most of the time, the default values can be used. + - The *mode* of the version management system to experiment mode, and the *version_number* is + set to "1.0.0".
+ Please refer to the [Version management configuration](../../../manuals/core/versioning/configuration.md) + documentation page for more details. - In lines 9, a custom *application_name* property are specified. ## SQL storage for Taipy entities -The configuration needed to use a SQL database, through sqlite3 engine, is described in the lines 6-7. +The configuration needed to use a SQL database, through sqlite3 engine, is described in the +lines 6-7. ```python linenums="1" from taipy import Config @@ -84,12 +94,11 @@ Config.configure_core( repository_properties={"db_location": "path_to_sqlite_file/database.db"}, ) ``` -Taipy creates a table called `taipy_model` in the database described in the configuration, where it stores -information about the taipy entities. - +Taipy creates a table called `taipy_model` in the database described in the configuration, where +it stores information about the taipy entities. Here are the configurable properties for the SQL repository: - - _**db_location**_: The path of a sqlite3 database file. + - _**db_location**_: The path of a sqlite3 database file. ## MongoDB storage for Taipy entities @@ -116,16 +125,17 @@ Config.configure_core( ) ``` -Taipy will create a collection, in the database described in the configuration, for each Taipy entity (`Cycle^`, -`Scenario^`, `DataNode^`, `Task^` and `Job^`), where it will store information about the Taipy -entities. +Taipy will create a collection, in the database described in the configuration, for each Taipy +entity (`Cycle^`, `Scenario^`, `DataNode^`, `Task^` and `Job^`), where it will store information +about the Taipy entities. Here are the configurable properties for the Mongo repository: - _**mongodb_hostname**_: The URL for the mongo database. - _**mongodb_user**_: The username to access the database. - _**mongodb_password**_: The password to access the database. - - _**mongodb_port**_: The port to access the database. This property is optional and has 27017 as a default value. + - _**mongodb_port**_: The port to access the database. This property is optional and has 27017 + as a default value. - _**application_db**_: The database that will hold the taipy collections. [:material-arrow-right: The next section introduces the job orchestration configuration](job-config.md). diff --git a/docs/manuals/core/config/data-node-config.md b/docs/manuals/core/config/data-node-config.md index dc16adba2..b7b54d641 100644 --- a/docs/manuals/core/config/data-node-config.md +++ b/docs/manuals/core/config/data-node-config.md @@ -135,7 +135,7 @@ The default `SCENARIO` scope is used. Since the data node config corresponds to pre-existing pickle file, a default path "path/to/my/model.p" is provided. We also added an optional custom description. -!!! Note +!!! note To configure a pickle data node, it is equivalent to using the method `Config.configure_pickle_data_node()^` or the method `Config.configure_data_node()^` @@ -199,7 +199,7 @@ In lines 18-21, we add another CSV data node configuration with the identifier " The default `SCENARIO` scope is used again. Since we have a custom class called `SaleRow` that is defined for this CSV file, we provide it as the *exposed_type* parameter. -!!! Note +!!! note To configure a CSV data node, it is equivalent to using the method `Config.configure_csv_data_node()^` or the method `Config.configure_data_node()^` @@ -273,7 +273,7 @@ In lines 17-21, we add another Excel data node configuration. The identifier is pre-defined for this Excel file, we provide it in the exposed_type**. We also provide the list of specific sheets we want to use as the *sheet_name* parameter. -!!! Note +!!! note To configure an Excel data node, it is equivalent to using the method `Config.configure_excel_data_node()^` or the method `Config.configure_data_node()^` @@ -281,7 +281,7 @@ the list of specific sheets we want to use as the *sheet_name* parameter. ## SQL Table -!!! Important +??? note - To be able to use a `SQLTableDataNode^` with Microsoft SQL Server you need to run internal dependencies with `pip install taipy[mssql]` and install your corresponding @@ -366,7 +366,7 @@ this SQL table data node will read and write to the SQLite database stored at "d When the data node is read, it reads all the rows from the table "sales", and when the data node is written, it deletes all the data in the table and insert the new data. -!!! Note +!!! note To configure a SQL table data node, it is equivalent to using the method `Config.configure_sql_table_data_node()^` or the method `Config.configure_data_node()^` @@ -374,7 +374,7 @@ data node is written, it deletes all the data in the table and insert the new da ## SQL -!!! Important +??? note - To be able to use a `SQLDataNode^` with Microsoft SQL Server you need to install internal dependencies with `pip install taipy[mssql]` and install your corresponding @@ -471,7 +471,7 @@ Here, the database username and password are unnecessary. The folder containing file is "database", with the file extension is ".sqlite3". Since the database name is "taipy", this SQL table data node will read and write to the SQLite database stored at "database/taipy.sqlite3". -!!! Note +!!! note To configure a SQL data node, it is equivalent to using the method `Config.configure_sql_data_node()^` or the method `Config.configure_data_node()^` @@ -557,7 +557,7 @@ and *decoder*: "sales_history". The default `SCENARIO` scope is used. The encoder and decoder are the custom encoder and decoder defined above. -!!! Note +!!! note To configure a JSON data node, it is equivalent to using the method `Config.configure_json_data_node()^` or the method `Config.configure_data_node()^` @@ -600,7 +600,7 @@ section, the following parameters can be provided: `read_kwargs= {"engine": "fastparquet", "compression": "gzip"}` will override the *engine* and *compression* properties of the data node. -!!! Tip +!!! tip The `ParquetDataNode.read_with_kwargs^` and `ParquetDataNode.write_with_kwargs^` methods provide an alternative for specifying keyword arguments at runtime. See examples @@ -654,13 +654,13 @@ Note that even though line 10 specifies the *compression* as "snappy", since the key was also provided in the _write_kwargs_ dictionary on line 4, the last value is used, hence the *compression* is None. -!!! Note +!!! note To configure a Parquet data node, it is equivalent to using the method `Config.configure_parquet_data_node()^` or the method `Config.configure_data_node()^` with parameter `storage_type="parquet"`. -!!! Info +!!! info Taipy ParquetDataNode wraps [`pandas.read_parquet`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_parquet.html) @@ -724,7 +724,7 @@ Without these two methods, the default decoder will map the key of each document the corresponding property of a `DailyMinTemp` object, and the default encoder will convert `DailyMinTemp` object's properties to a dictionary without any special formatting. -!!! Note +!!! note To configure a Mongo collection data node, it is equivalent to using the method `Config.configure_mongo_collection_data_node()^` or the method `Config.configure_data_node()^` @@ -752,7 +752,7 @@ can be provided: - _**write_fct_args**_ represents the parameters passed to the *write_fct* to write the data. It must be a `List` type object. -!!! Note +!!! note At least one of the *read_fct* or *write_fct* is required to configure a generic data node. @@ -797,7 +797,7 @@ comments=false %} ``` -!!! Note +!!! note To configure a generic data node, it is equivalent to using the method `Config.configure_generic_data_node()^` or the method `Config.configure_data_node()^` @@ -825,12 +825,12 @@ comments=false In this example, we configure an *in_memory* data node with the id "date". The scope is `SCENARIO` (default value), and default data is provided. -!!! Warning +!!! warning Since the data is stored in memory, it cannot be used in a multi-process environment. (See [Job configuration](job-config.md#standalone) for more details). -!!! Note +!!! note To configure an in_memory data node, it is equivalent to using the method `Config.configure_in_memory_data_node()^` or the method `Config.configure_data_node()^` diff --git a/docs/manuals/core/config/index.md b/docs/manuals/core/config/index.md index 30266e859..8bcd3b435 100644 --- a/docs/manuals/core/config/index.md +++ b/docs/manuals/core/config/index.md @@ -21,7 +21,7 @@ your application and its entities. More details on the **entities** are available in the [Entities](../entities/index.md) chapter. -!!! important +!!! warning All configuration objects must be created before running Core service to avoid any conflict. diff --git a/docs/manuals/core/config/job-config.md b/docs/manuals/core/config/job-config.md index 5738d470f..7a04a7d94 100644 --- a/docs/manuals/core/config/job-config.md +++ b/docs/manuals/core/config/job-config.md @@ -36,13 +36,13 @@ The _development_ mode can be activated with the following config: mode = "development" ``` -!!! Note +!!! note Note that if no mode is configured, the development mode is used. # Standalone mode -!!! Warning +!!! warning We do not encourage using standalone mode in an interactive Python environment such as Jupyter Notebook or iPython. However, if you find the need for it, please note that when using the @@ -110,7 +110,7 @@ For example, the following configuration will allow Taipy to run up to eight `Jo nb_of_workers = "8:int" ``` -!!! Note +!!! note If no value is provided in the _nb_of_workers_ setting in the configuration, Taipy will set this value to 1. diff --git a/docs/manuals/core/config/scenario-config.md b/docs/manuals/core/config/scenario-config.md index b02c9a119..d13ad6ec0 100644 --- a/docs/manuals/core/config/scenario-config.md +++ b/docs/manuals/core/config/scenario-config.md @@ -167,7 +167,7 @@ Line 25 indicates that only the data nodes instantiated from `data_node_cfg` are The comments in lines 3-8, gives you an idea of what the `compare_function()` function computes depending on the given input parameters. -!!! Info +!!! info Please refer to the [scenario entity comparison](../entities/scenario-cycle-mgt.md) section to see how to compare scenarios using the comparators defined in a `ScenarioConfig^`. diff --git a/docs/manuals/core/entities/data-node-mgt.md b/docs/manuals/core/entities/data-node-mgt.md index 084905da3..4b5a2fb4a 100644 --- a/docs/manuals/core/entities/data-node-mgt.md +++ b/docs/manuals/core/entities/data-node-mgt.md @@ -43,7 +43,7 @@ This method is proper when you want to create a data node that is independent of you can create a data node that stores the dataset for training a model, then filter, lock, or modify the data node independently from the scenarios. Afterward, you can use this data node in multiple scenarios. -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -52,7 +52,7 @@ independently from the scenarios. Afterward, you can use this data node in multi sale_history_datanode = tp.create_global_data_node(sales_history_cfg) ``` -!!! Warning +!!! warning The `taipy.create_global_data_node()^` method only accepts data node configuration with `GLOBAL` scope. If a data node configuration with a different scope is provided, the method will raise the @@ -65,7 +65,7 @@ independently from the scenarios. Afterward, you can use this data node in multi The first method to access a **data node** is by calling the `taipy.get()^` method passing the data node id as a parameter: -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -84,7 +84,7 @@ passing the data node id as a parameter: The data nodes that are part of a **scenario**, **sequence**, or **task** can be directly accessed as attributes by using their config_id: -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -110,7 +110,7 @@ using their config_id: Data nodes can be retrieved by using `taipy.get_entities_by_config_id()^` providing the config_id. This method returns the list of all existing data nodes instantiated from the config_id provided as a parameter. -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -129,7 +129,7 @@ This method returns the list of all existing data nodes instantiated from the co All data nodes that are part of a **scenario** or a **sequence** can be directly accessed as attributes: -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -150,7 +150,7 @@ All data nodes that are part of a **scenario** or a **sequence** can be directly All the data nodes can be retrieved using the method `taipy.get_data_nodes()^` which returns a list of all existing data nodes. -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -166,7 +166,7 @@ data nodes. To access the content of a data node you can use the `DataNode.read()^` method. The read method returns the data stored in the data node according to the type of data node: -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -186,7 +186,7 @@ To write some data on the data node, like the output of a task, you can use the method takes a data object (string, dictionary, lists, NumPy arrays, Pandas dataframes, etc. based on the data node type and its exposed type) as a parameter and writes it on the data node: -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -1152,7 +1152,7 @@ to the data node. Correspondingly, In memory data node can write any data object that is valid data for a Python variable. -!!! Warning +!!! warning Since the data is stored in memory, it cannot be used in a multiprocess environment. (See [Job configuration](../config/job-config.md#standalone) for more details). @@ -1182,7 +1182,7 @@ temp_data = data_node["field_name"] temp_data[(temp_data == 14) | (temp_data == 10)] ``` -!!! Warning +!!! warning For now, the `DataNode.filter()^` method is only implemented for `CSVDataNode^`, `ExcelDataNode^`, `SQLTableDataNode^`, `SQLDataNode` with `"pandas"` as the _**exposed_type**_ value. @@ -1192,7 +1192,7 @@ temp_data[(temp_data == 14) | (temp_data == 10)] To get the parent entities of a data node (scenarios, sequences, or tasks) you can use either the method `DataNode.get_parents()^` or the function `taipy.get_parents()^`. Both return the parents of the data node. -!!! Example +!!! example ```python linenums="1" import taipy as tp diff --git a/docs/manuals/core/entities/orchestrating-and-job-execution.md b/docs/manuals/core/entities/orchestrating-and-job-execution.md index 6e36c4f44..4413b4be7 100644 --- a/docs/manuals/core/entities/orchestrating-and-job-execution.md +++ b/docs/manuals/core/entities/orchestrating-and-job-execution.md @@ -4,9 +4,9 @@ In a Taipy application, running the Core service is required to execute jobs. To can run different Taipy services, please refer to the [Running Taipy services](../../run-deploy/run/running_services.md) page. -!!! important "Preventing configuration update when the Taipy Core service is running" +!!! note "Preventing configuration update when the Taipy Core service is running" - After running the Core service, all configuration will be blocked from update to prepare for job execution. + After running the Core service, all configuration are blocked from update. In this section, it is assumed that `my_config.py` module contains a Taipy configuration already implemented. @@ -41,7 +41,7 @@ tp.submit(scenario) tp.Core().run() ``` -!!! Note "Another syntax." +!!! note "Another syntax." To submit a scenario, you can also use the method `Scenario.submit()^`: ```python linenums="1" @@ -94,7 +94,7 @@ In line 5, we retrieve the sequence named `sales_sequence` from the created scen sequence for execution. The `taipy.submit()^` method triggers the submission of all the sequence's tasks. When submitting a sequence, you can also use the two parameters _wait_ and _timeout_. -!!! Note "Another syntax." +!!! note "Another syntax." To submit a sequence, you can also use the method `Sequence.submit()^`: ```python linenums="1" @@ -125,7 +125,7 @@ job = tp.submit(task) In line 5, we retrieve the task named `predicting` from the created scenario. In line 7, we submit this task for execution. When submitting a task, you can also use the two parameters _wait_ and _timeout_. -!!! Note "Another syntax." +!!! note "Another syntax." To submit a task, you can also use the method `Task.submit()^`: ```python linenums="1" @@ -180,7 +180,7 @@ Deleting a Job can raise an `JobNotDeletedException^` if the `Status^` of the Jo `FAILED`. You can overcome this behaviour by forcing the deletion with the _force_ parameter set to True: `taipy.delete_job(job, force=True)`. -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -355,7 +355,7 @@ You can also unsubscribe to scenarios by using `taipy.unsubscribe_scenario(funct or `tp.unsubscribe_sequence(function)` for sequences. Same as for subscription, the un-subscription can be global, or you can specify the scenario or sequence by passing it as a parameter. -!!! Example +!!! example ```python linenums="1" import taipy as tp diff --git a/docs/manuals/core/entities/scenario-creation.md b/docs/manuals/core/entities/scenario-creation.md index 3f7ac7cbd..9cceea0d3 100644 --- a/docs/manuals/core/entities/scenario-creation.md +++ b/docs/manuals/core/entities/scenario-creation.md @@ -36,7 +36,7 @@ Three parameters can be given to the scenario creation method : - The `name` parameter is optional as well. Any string can be provided as a `name`. It can be used to display the scenario in a user interface. -!!! Example +!!! example === "Scenario creation with parameters" Using the [`my_config.py`](./code_example/my_config.py) module, here is an example of how to create a scenario. diff --git a/docs/manuals/core/entities/scenario-cycle-mgt.md b/docs/manuals/core/entities/scenario-cycle-mgt.md index 76786e0ae..ce738ec3a 100644 --- a/docs/manuals/core/entities/scenario-cycle-mgt.md +++ b/docs/manuals/core/entities/scenario-cycle-mgt.md @@ -34,7 +34,7 @@ generated by Taipy. A scenario also holds various properties, each accessible as - Each nested entity is also exposed as an attribute of the scenario. The attribute name corresponds to the _config_id_ of the nested entity. -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -90,7 +90,7 @@ Here, the two variables `scenario` and `scenario_retrieved` are equal. Scenarios can also be retrieved using `taipy.get_entities_by_config_id()^` providing the config_id. This method returns the list of all existing scenarios instantiated from the config_id provided as a parameter. -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -163,7 +163,7 @@ tp.compare_scenarios(previous_month_scenario, data_node_config_id="sales_predictions") ``` -!!! Important +!!! note To specify how to compare scenarios on data nodes, you need to define comparison functions. Please refer to the [Scenario Config](../config/scenario-config.md) page. @@ -264,7 +264,7 @@ attributes and properties, each accessible as an attribute of the cycle: - _**name**_ corresponds to a user readable name of this cycle. - Each property of the _**properties'**_ dictionary is also directly exposed as an attribute. -!!! Example +!!! example ```python linenums="1" import taipy as tp diff --git a/docs/manuals/core/entities/sequence-mgt.md b/docs/manuals/core/entities/sequence-mgt.md index e29d1496e..fc7bd823d 100644 --- a/docs/manuals/core/entities/sequence-mgt.md +++ b/docs/manuals/core/entities/sequence-mgt.md @@ -26,7 +26,7 @@ add data_nodes, parent_ids - Each nested entity is also exposed as an attribute of the sequence. The attribute name corresponds to the *config_id* of the nested entity. -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -89,7 +89,7 @@ To get the parent entities of a sequence (i.e., scenarios) you can use either th the function `taipy.get_parents()^`. Both return the parents of the sequence. -!!! Example +!!! example ```python linenums="1" import taipy as tp diff --git a/docs/manuals/core/entities/task-mgt.md b/docs/manuals/core/entities/task-mgt.md index 23ae139cc..e6f4e10ba 100644 --- a/docs/manuals/core/entities/task-mgt.md +++ b/docs/manuals/core/entities/task-mgt.md @@ -27,7 +27,7 @@ A task also holds various properties accessible as an attribute of the task: [Data node management page](../entities/data-node-mgt.md) for more detail). The default value of *skippable* is False. -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -87,7 +87,7 @@ task_2 = sequence.predicting # "predicting" is the config_id of the predicting Tasks can also be retrieved using `taipy.get_entities_by_config_id()^` providing the config_id. This method returns the list of all existing tasks instantiated from the config_id provided as a parameter. -!!! Example +!!! example ```python linenums="1" import taipy as tp @@ -108,7 +108,7 @@ To access the parent entities of a task (scenarios or sequences), you can use either the method `Task.get_parents()^` or the function `taipy.get_parents()^`. Both return the parents of the task. -!!! Example +!!! example ```python linenums="1" import taipy as tp diff --git a/docs/manuals/core/versioning/experiment_mode.md b/docs/manuals/core/versioning/experiment_mode.md index d9b980c1b..62dd35ba9 100644 --- a/docs/manuals/core/versioning/experiment_mode.md +++ b/docs/manuals/core/versioning/experiment_mode.md @@ -145,7 +145,7 @@ Number of scenarios: 2 As you can see on the previous example, the application run correctly after updating the configuration. A new scenario has been created. -!!! Warning +!!! warning By forcing the configuration update, you must be aware that old entities instantiated before the configuration change may not be compatible. diff --git a/docs/manuals/core/versioning/production_mode.md b/docs/manuals/core/versioning/production_mode.md index 6f6a2339f..8dfec2903 100644 --- a/docs/manuals/core/versioning/production_mode.md +++ b/docs/manuals/core/versioning/production_mode.md @@ -139,7 +139,7 @@ $ taipy run main.py --production 1.0 --force As you can see, the application is run successfully after updating the configuration. -!!! Warning +!!! warning By forcing the configuration update, you must be aware that old entities instantiated before the configuration change may not be compatible. diff --git a/docs/manuals/gui/binding.md b/docs/manuals/gui/binding.md index b79c68c75..c6436bda8 100644 --- a/docs/manuals/gui/binding.md +++ b/docs/manuals/gui/binding.md @@ -66,7 +66,7 @@ module, then the variable is sought in the *\_\_main\_\_* module (typically, whe We call *page scopes* the context where the variables are located: first, the module where the page is defined, then the main module. -!!! important "Defining a page scope" +!!! note "Defining a page scope" A page scope, where variables used in a page definition are searched, is the module where the page *instance* (an instance of the `Markdown^` or the `Html^` classes), **not** the text of the page. @@ -150,7 +150,7 @@ rely on page scopes to determine which is invoked when a callback is triggered: GUI favors the callback functions that are defined in the module where the page itself is defined. -!!! important "Global callback functions" +!!! note "Global callback functions" The way you can define local callback functions does not apply to global callbacks such as `on_action()`. There can be only one global callback, defined in the main module. diff --git a/docs/manuals/gui/configuration.md b/docs/manuals/gui/configuration.md index bcc30e075..6cd635858 100644 --- a/docs/manuals/gui/configuration.md +++ b/docs/manuals/gui/configuration.md @@ -71,7 +71,8 @@ Here is the list of the configuration parameters you can use in indicates how far from the border of the windows should your interface be. The default value avoids elements getting glued to the window borders, improving appearance. - *system_notification* (bool, default: True): if True, - notifications will be sent by the system as well as the browser, should the *system_notification* parameter in the call to (`notify()^`) be set to None. If False, the + notifications will be sent by the system as well as the browser, should the + *system_notification* parameter in the call to (`notify()^`) be set to None. If False, the default behavior is to not use system notifications.
See the section on [Notifications](notifications.md) for details. - *notification_duration* (int, default: 3000): the time, @@ -113,11 +114,11 @@ Here is the list of the configuration parameters you can use in [Accessing your app from the Web](#accessing-your-app-from-the-web) for details. - *change_delay* (int, default: None): the delay, in milliseconds, used by some controls (namely [`slider`](viselements/slider.md), - [`input`](viselements/input.md), and [`number`](viselements/number.md)) before the user actions - are sent to the backend server for further processing. This can be used when there is a - significant network latency: user actions would then get stacked up on the front-end before the - back-end had a chance to receive them, resulting in a poor user experience. This value should - be less than 300 to ensure a smooth interaction with the control.
+ [`input`](viselements/input.md), and [`number`](viselements/number.md)) before the user + actions are sent to the backend server for further processing. This can be used when there is + a significant network latency: user actions would then get stacked up on the front-end before + the back-end had a chance to receive them, resulting in a poor user experience. This value + should be less than 300 to ensure a smooth interaction with the control.
The default value of None indicates that Taipy GUI does not use any delay. - *propagate* (bool, default: True): the default value that is used for every *propagate* property value, for all controls. Please look at the section on the @@ -143,15 +144,15 @@ Here is the list of the configuration parameters you can use in can be found in the documentation section for [Plotly's layout template](https://plotly.com/javascript/reference/layout/#layout-template). - *extended_status* (bool, default: False): if set to True, the - [status page](pages.md#status-page) output is augmented with additional information. + [status page](pages/index.md#status-page) output is augmented with additional information. - *flask_log* (bool, default: False): if set to True, you can get a complete, real-time log from the Flask server. This may be useful when trying to find out why a request does not behave as expected. - - *notebook_proxy* (bool, default: True): this setting only matters - when running Taipy GUI in the context of Notebooks. If set to True, which is the default, the - exposed port number (the one set in the [*port*](#p-port) parameter) is just a proxy port to a - dynamically generated port so that the user can stop and restart the server without depending - on how quickly the kernel can clean up its resources.
+ - *notebook_proxy* (bool, default: True): this setting only + matters when running Taipy GUI in the context of Notebooks. If set to True, which is the + default, the exposed port number (the one set in the [*port*](#p-port) parameter) is just a + proxy port to a dynamically generated port so that the user can stop and restart the server + without depending on how quickly the kernel can clean up its resources.
See the section on [running Taipy GUI in Notebooks](notebooks.md) for more details. - *single_client* (bool, default: False): set to True if only a single client can connect. False, which is the default value, indicates that multiple clients @@ -194,8 +195,8 @@ Here is the list of the configuration parameters you can use in or run the server, and it is up to the programmer to use the Flask instance returned by `Gui.run()^` or `Gui.get_flask_app()^` so it is served by the target web server. - *base_url* (str or None, default: "/"): a string used as a prefix to - the path part of the exposed URL, so one can deploy a Taipy GUI application in a path different - from the root of the web site. + the path part of the exposed URL, so one can deploy a Taipy GUI application in a path + different from the root of the web site. - *allow_unsafe_werkzeug* (bool, default: False): hides some [Flask-SocketIO](https://pypi.org/project/Flask-SocketIO/) runtime errors in some debugging scenarios. This is set to True when [*debug*](#p-debug) is set to True. diff --git a/docs/manuals/gui/corelements/scenario_selector.md_template b/docs/manuals/gui/corelements/scenario_selector.md_template index 58b9a46ed..2e19ea055 100644 --- a/docs/manuals/gui/corelements/scenario_selector.md_template +++ b/docs/manuals/gui/corelements/scenario_selector.md_template @@ -1,4 +1,4 @@ -Select scenarios from the list of all Taipy Core scenario entities. +Select scenarios from the list of all scenario entities. The scenario selector shows all the scenario entities handled by Taipy Core and lets the user select a scenario from a list, create new scenarios or edit existing scenarios. diff --git a/docs/manuals/gui/index.md b/docs/manuals/gui/index.md index 0c521403a..da94a8c3f 100644 --- a/docs/manuals/gui/index.md +++ b/docs/manuals/gui/index.md @@ -26,11 +26,13 @@ Users can also interact with some of those elements to trigger application code that can change the displayed information, produce more data to visualize or move to a completely different page. -The generated web pages are built from a set of template text files that you -provide, where you would have planted placeholders that will display application -data. The application end users can then see and interact with the application. We call these representative and interactive objects: *visual elements*. +The generated web pages are built from a set of template text files that you provide, where you +would have planted placeholders that will display application data. The application end users can +then see and interact with the application. We call these representative and interactive objects: +*visual elements*. -To describe the content of pages, Taipy comes the support for two template formats, handled by the classes `Markdown^` and `Html^`. +To describe the content of pages, Taipy comes the support for two template formats, handled by the +classes `Markdown^` and `Html^`. The basic principle is that you create pages as you need them, give them a name so you can indicate to your browser how to access these pages, and provide these pages to @@ -42,6 +44,7 @@ when Taipy transforms the page you had created into some HTML content sent back to the client so the user can see the application interface and start using it. -!!! info "You can find more information on how pages are created and used in Taipy application in the [Pages](pages.md) section." +!!! info "You can find more information on how pages are created and used in Taipy application in +the [Pages](pages/index.md) section." !!! info "To run the Taipy GUI service with some other Taipy services, please refer to the [Running Taipy services](../run-deploy/run/running_services.md) page" diff --git a/docs/manuals/gui/notebooks.md b/docs/manuals/gui/notebooks.md index 93be593d5..8299c0dc4 100644 --- a/docs/manuals/gui/notebooks.md +++ b/docs/manuals/gui/notebooks.md @@ -5,27 +5,27 @@ so the Notebook works as expected. # Creating a Taipy GUI application in a new Notebook -Here is a step-by-step approach on hosting a Taipy GUI within your Notebook +Here is a step-by-step approach to hosting a Taipy GUI within your Notebook and interacting with it. You will start your Jupyter server the usual way: ```py jupyter notebook ``` -Your browser should open a new window, connected to the Jupyter server, where you can create +Your browser should open a new window connected to the Jupyter server, where you can create and manipulate Notebooks. -!!! Note "Example code" +!!! note "Example code" You may want to load the [Notebook source](gui_example.ipynb) file directly within Jupyter and move from cell to cell instead of entering the code in the following steps. Create a new Notebook by selecting the *New* > *Python 3 (ipykernel)* option located in the upper right corner of the Jupyter interface.
-Then start creating the Notebook content. +Then, start creating the Notebook content. Enter the following code into the first Notebook cell: -```python linenums="1" +```py title="Cell [1]" linenums="1" from taipy.gui import Gui, Markdown page = Markdown(""" @@ -44,10 +44,11 @@ gui.run() As you can see, we create and run our `Gui^` instance in lines 13 and 14. -Note that we use the `Markdown^` class explicitly (in line 3). That is because later in our code, +Note that we use the `Markdown^` class explicitly (in line 3). That is because, later in our code, we will want to modify the content of the page. -Run the cell. The output shows that a server was started (usually on *http://127.0.0.1:5000*), +Run the cell.
+The output shows that a server was started (usually on *http://127.0.0.1:5000*), hosting the 'Taipy' Flask app.
A new window is created in your browser, displaying the small interface we have just created.
Note that the text control automatically displays *value* when you move the slider thumb. That @@ -57,6 +58,34 @@ shows that Taipy has successfully bound the variable *value* to both the You can witness the user interface update when you change a variable on the fly. In the context of Notebooks, you can directly access the variables that are bound to the user interface: +# Updating pages + +Pages can also be updated on-the-fly. + +In the case when you do *not* use new variables in the new page content, you can simply use the +`(Page^).set_content()` method of the `Page^` class to update the content of the page.
+In our example, that would mean calling this method on the *page* object. + +Enter the following code into a new Notebook cell to test it out: + +```py title="Cell [2]" +page.set_content(""" +# Taipy in a Notebook + +Value: <|{value}|> + +Set: <|{value}|slider|> + +As a number field: <|{value}|number|> +""") +``` + +All we did was add a `number` control to the page, bound to the same variable *value*. + +Run this cell and refresh the page in the browser to see this control appear, showing the variable +value as it was set before. Changing the value in the number field or the slider will update it in +all three controls. + # Updating variables The point of using Notebooks (besides making it possible to provide explanatory text along with the @@ -64,29 +93,34 @@ code in a single document) is to allow for changing variables on the fly and see these changes immediately. Let's see how we can use that feature with Taipy. Enter the following line into a new cell: -```py +```py title="Cell [3]" gui.state.value = 50 ``` -When you run this cell, the new value is reflected both in the text and the slider. +When you run this cell, the new value is reflected in the text, the slider, and the number field. +There is no need to refresh the application page. -!!! important "The gui.state property" +!!! note "The gui.state property" This property is provided **only** in the context of Notebooks, where there is a single - connection to the server, allowing to access a single '*state*'. + connection to the server, allowing to access a unique '*state*'. -# Updating pages +# Adding variable bindings -Pages can also be updated on-the-fly. +A more complicated case is where new variables are introduced within the updated content of a page. +In this situation, you must update the content of the page with the `(Page.)set_content()^` method +just like above, then *reload* the application context using the `Gui.reload()^` method on the +*gui* object. +This is an example of where this must be done.
In another cell, enter the following text: -```py +```py title="Cell [4]" import math xrange = range(0, 720) -def compute_data(a): - return [ a * math.cos(2 * math.pi * x / 100) + - (100-a) * math.sin(2 * math.pi * x / 50) +def compute_data(v): + return [ v * math.cos(2 * math.pi * x / 100) + + (100-v) * math.sin(2 * math.pi * x / 50) for x in xrange] data = compute_data(value) @@ -96,10 +130,9 @@ After running this cell, the variable *data* holds an array of floating-point va some fancy trigonometric function (computed in *compute_data()*) based on some parameter. If we want to display these values in a chart, we need to change our page to add a -[`chart`](viselements/chart.md) control to it.
+[`chart`](viselements/chart.md) control to it (and remove the `number` control).
You can update the page content on the fly by creating a new cell with the following content: - -```py +```py title="Cell [5]" page.set_content(""" # Taipy in a Notebook @@ -111,38 +144,58 @@ Set: <|{value}|slider|> """) ``` +Run this cell.
If you refresh the page where the interface is displayed, you will see that the `chart` control -appears just like you expected. +appears, but with no data. You also get warnings from Taipy indicating that the *data* variable +could not be found. + +To make the `Gui` instance aware of the *data* variable, you must *reload* the server.
+You can do that by creating a new cell with the following content: +```py title="Cell [6]" +gui.reload() +``` +When you run this cell, your browser displays your application page, with the *data* variable +properly bound to the `chart` control. + +Note that `gui.reload()` is equivalent to: +```py +gui.stop() +gui.run() +``` + +# Adding interaction A final step we can take is to add some interaction to this application.
We want the data recomputed when the sider value is modified and witness the chart reflect that change. -Create a final cell and enter the following: +Create another cell and enter the following: -```py +```py title="Cell [7]" def on_change(state, var_name, var_value): - if var_name == "value": - state.data = compute_data(state.value) + if var_name == "value": + state.data = compute_data(state.value) ``` +Then, run this cell. -The code in this cell updates the data displayed in the user interface when the variable *value* -changes (that is, when the user moves the slider thumb).
-However, the `Gui` object was initially created without knowing this function that it must bind -controls to. To reset the Taipy server and connect to *on_change()*, you must run the final cell: +The code in this cell implements a callback function that gets called when controls on the page +trigger the `on_change` callback. This function updates the data displayed in the user +interface when the variable *value* changes (when the user moves the slider thumb).
+However, the `Gui` object was initially created without knowing about this function that it must +bind controls to. To reset the Taipy server and connect to *on_change()*, you must run the final +cell: -```py -gui.stop() -gui.run() +```py title="Cell [8]" +gui.reload() ``` -Go to the Taipy interface page and refresh.
-The slider now controls the chart that is automatically updated when a new value is set. +The page appears in your browser. The slider now controls the chart that is automatically updated +when a new value is set. !!! note "Restarting the web server" - Some Notebook environments are not able to restart the underlying web server so that Taipy GUI + Some Notebook environments cannot restart the underlying web server so that Taipy GUI can immediately reuse the port number it was communicating with. To cope with this problem, in - the context of Notebooks only, the port number that is used as part of the application URL is a - proxy to the real port that is served. Invoking `run()` after `stop()` generates a hidden port + the context of Notebooks only, the port number used as part of the application URL is a + proxy to the real served port. Invoking `run()` after `stop()` generates a hidden port number that gets used transparently. This behavior is controlled by the [*notebook_proxy*](configuration.md#p-notebook_proxy) configuration setting. diff --git a/docs/manuals/gui/page_builder.md b/docs/manuals/gui/page_builder.md new file mode 100644 index 000000000..cf35a0bf0 --- /dev/null +++ b/docs/manuals/gui/page_builder.md @@ -0,0 +1,215 @@ +The Page Builder API is a set of classes located in the +[`taipy.gui.builder`](../reference/pkg_taipy.gui.builder.md) package that lets users +create Taipy GUI pages entirely from Python code. + +This package contains a class for every visual element available in Taipy, including those +defined in [extension libraries](extension/index.md). + +To access the Page Builder classes, you must import the +[`taipy.gui.builder`](../reference/pkg_taipy.gui.builder.md) package in your script. + +# Generating a new page + +To create a new page, you must call the `(taipy.gui.builder.)Page^` constructor. This +object not only represents a page, but is also a +[Python context manager](https://docs.python.org/3/library/contextlib.html): You will create the +elements this page holds within the `with` block. + +Here is an example of how to create a page using the Page Builder: +```py +from src.taipy.gui import Gui +import src.taipy.gui.builder as tgb + + +with tgb.Page() as page: + # add your visual elements here + +Gui(page).run() +``` + +Elements are added in the `with` block for the *page* object.
+Then, the page is added to the `Gui` instance, as it would be done for any other page type. + +# Adding elements + +Creating the element classes within a Page context is enough to add them to the page: +```py +with tgb.Page() as page: + tgb.input() +``` + +In this example, we add an empty [`input`](viselements/input.md) control.
+When run, the application would show a page looking like this: +
+ + +
An empty input field
+
+ +Note that elements can also be added to a page using the `(builder.)Page.add()^` method.
+The code above could have been written as: +```py +page = tgb.Page() +page.add(tgb.input()) +``` + +# Setting property values + +Let's now add another element and set the element properties to achieve something more +significant: +``` +with tgb.Page() as page: + tgb.html("p", "User information:") + tgb.input("John", label="First name") +``` + +The `html^` element lets us add a label to the page showing the text content of the generated +`

` tag. + +This code could have been written differently for an identical result: +```py +page = tgb.Page() +page.add(tgb.html("p", "User information:")).add(tgb.input("John", label="First name")) +``` + +Note how, in the `input^` control, we use the property names of the control as parameters to the +class constructor. +
+The first parameter is set to the element's default property. Because *value* is the default +property for the [`input`](viselements/input.md) control, we could have built the control using: +```py + tgb.input(label="First name", value="John") +``` +And the result would be exactly identical. + +Now, here is what the page looks like after those changes: +

+ + +
More relevant elements
+
+ +The `html^` element can also be set specific properties. The name and values of the properties +must be valid from the HTML standard standpoint. + +Here is how we could modify the creation of the `html` element by changing its style: +``` + tgb.html("p", "User information:", style="font-weight:bold;") +``` + +The impact of this change is reflected in the page: + +
+ + +
Styling HTML
+
+ +Compared to the previous example, you can see that the label uses a bold font weight. + +# Binding variables + +You can bind your application variables to a property value by setting the property to a string +that contains a Python expression that depends on the variables. + +Here is how we would use a Python variable to hold the text handled in the `input` control we +have used so far.
+The new code looks like this: +```py +first_name="John" + +with tgb.Page() as page: + tgb.html("p", "User information:") + tgb.input("{first_name}", label="First name") +``` + +And the result is identical to what was shown above. + +# Using blocks + +The Taipy GUI blocks can help organize the elements on the page. + +In the following code, we use the `layout^` block to organize the controls on the page: +```py +first_name="John" +last_name="Carpenter" +age=43 + +with tgb.Page() as page: + tgb.html("p", "User information:") + with tgb.layout("4 1"): + with tgb.part(): + tgb.input("{first_name}", label="First name") + tgb.input("{last_name}", label="Last name") + tgb.input("{age}", label="Age") + tgb.button("Submit") +``` + +The `layout` block is defined as having two columns, where the first column is four times larger +than the second one. + +Here is the resulting display: +
+ + +
Controls layout
+
+ +# Invoking callbacks + +Because you can set functions to callback properties, the binding to callback functions is more +flexible than when you define page content using text. + +## Default callbacks + +Default callbacks are invoked if not explicitly assigned to callback properties. + +Consider the following script: +```py +from src.taipy.gui import Gui +import src.taipy.gui.builder as tgb + +def on_action(state, id): + if id == "my_button": + # Do something... + pass + +with tgb.Page() as page: + tgb.button("Press me", id="my_button") + +Gui(page).run() +``` + +The `button^` does not define its *on_action* property: Taipy looks for an *on_action()* function +in the code and invokes it when the button is pressed. + +## Named callbacks + +The name of the callback function can also be used as a callback property value. + +The code changes would be like this: +```py +def my_button_pressed(state, id): + # Do something... + pass + +with tgb.Page() as page: + tgb.button("Press me", on_action="my_button_pressed") +``` + +The `button^` does not define its *on_action* property: Taipy looks for a *on_action()* function +in the code and invokes it when the button is pressed. + +## Functions as callbacks + +You can also use the Python function as a callback property value: +```py +def my_button_pressed(state, id): + # Do something... + pass + +with tgb.Page() as page: + tgb.button("Press me", on_action=my_button_pressed) +``` + +This would have the same behavior as in the case where you would have used the function name. diff --git a/docs/manuals/gui/pages.md b/docs/manuals/gui/pages/index.md similarity index 87% rename from docs/manuals/gui/pages.md rename to docs/manuals/gui/pages/index.md index f1b14a43c..e40fbbc45 100644 --- a/docs/manuals/gui/pages.md +++ b/docs/manuals/gui/pages/index.md @@ -4,10 +4,21 @@ interact with the application data through visual elements. # Defining pages -Taipy lets you create as many pages as you want, with whatever content you need. -Pages are created using sub-classes of the (`Page^`) class which convert some text -(inside the application code or from an external file) into HTML content sent and -rendered on the client device. +Taipy lets you create as many pages as you want, with whatever content you need.
+Pages can be defined using two different techniques: + +- you can create a textual description of the page (inside the application code or from an external + file) that will get transformed into HTML content sent and rendered on the client device. +- you can create pages entirely by code, using the [Page Builder](../page_builder.md) package.
+ This package provides a way to create any visual element, organize them within blocks, and + create pages to hold them. + +This section focuses exclusively on the text-to-page process, which is the typically preferred +manner: the text provides kind of a preview of the page and can also structure the elements.
+If you want to generate page content, the [Page Builder](../page_builder.md) API may be a better +fit: using the Python language, you can create loops or conditionals that would otherwise be +complicated to produce with a text-only description. Please refer to +[this section](../page_builder.md) if this is what you need. Converting text into page content is done according to these steps: @@ -20,7 +31,7 @@ Converting text into page content is done according to these steps: - Potentially, *callbacks* are located and connected from the rendered page back to the Python code in order to watch user events (the notion of callbacks is detailed - in the section [Callbacks](callbacks.md)). + in the section [Callbacks](../callbacks.md)). ## Defining the page content @@ -72,7 +83,7 @@ Any [*Markdown*](https://en.wikipedia.org/wiki/Markdown) content can be used her You then have, in the *md_page* variable, the definition of a page whose content is defined by Markdown text. -!!! Note "Markdown link syntax" +!!! note "Markdown link syntax" You can use Markdown's native *link* syntax to easily create links from one page to another. @@ -89,7 +100,7 @@ whose content is defined by Markdown text. Besides the extensions listed above, Taipy adds its own extension that can parse Taipy-specific constructs that allow for defining visual elements (and all the properties they need). The details on how visual elements are located and interpreted with Markdown -content can be found in the [Markdown Syntax](viselements/index.md#markdown) section +content can be found in the [Markdown Syntax](../viselements/index.md#markdown) section about Visual Elements definition. ### Using HTML @@ -115,7 +126,7 @@ whose content is defined from HTML text. Taipy identifies visual element definitions by finding tags that belong to the `taipy` namespace. You can find details on how to create visual -elements using HTML in the [HTML Syntax](viselements/index.md#html) section +elements using HTML in the [HTML Syntax](../viselements/index.md#html) section about Visual Elements definition. ## Registering the page @@ -162,7 +173,7 @@ will be *localhost:5000/page1* or *localhost:5000/page2*. Note that if pages are created in different modules, the variables that they can bind to visual elements may have a scope limited to their origin module. See -[Page scopes](binding.md#scope-for-variable-binding) for more details. +[Page scopes](../binding.md#scope-for-variable-binding) for more details. ## Viewing the page @@ -173,7 +184,7 @@ values), so you can see your application's state and interact with it. # Root page The *Root* page is the page located at the top of the web application. -The name of this page is `"/"` (or the value of the [*base_url*](configuration.md#p-base_url) +The name of this page is `"/"` (or the value of the [*base_url*](../configuration.md#p-base_url) configuration setting). If your application uses only one page, this is typically where it would be created: @@ -189,7 +200,7 @@ be `http://127.0.0.1:5000/`). If your application has several pages, you would usually create them with different names, so the user can navigate from page to page (using the `navigate()^` function or the -[`navbar`](viselements/navbar.md) control).
+[`navbar`](../viselements/navbar.md) control).
However, you can still have a root page for your application (with the name: `"/"`). In this situation, Taipy creates a [single-page application (SPA)](https://en.wikipedia.org/wiki/Single-page_application) @@ -238,7 +249,7 @@ for all its pages. !!! tip "Running multiple services" If you need to run the Taipy GUI service with other Taipy services, you may need - to refer to the [Running Taipy services](../run-deploy/run/running_services.md) + to refer to the [Running Taipy services](../../run-deploy/run/running_services.md) section. ## The `<|content|>` pseudo-control @@ -281,7 +292,7 @@ Applications sometimes need to prompt the user to indicate a situation or reques input of some sort. Dialogs are forms that can be displayed on top of the page the user is looking at, prompting for some input. -To create a dialog, you will use a [`dialog`](viselements/dialog.md) control in your +To create a dialog, you will use a [`dialog`](../viselements/dialog.md) control in your page. The dialog holds a page content or a *Partial* (see [Partials](#partials)). You can control whether the dialog is visible or not, and what to do when the end-user @@ -308,7 +319,7 @@ user's response. Gui(page).run() ``` -Please refer to the documentation page on the [`dialog`](viselements/dialog.md) +Please refer to the documentation page on the [`dialog`](../viselements/dialog.md) control for more details and examples. # Partials @@ -341,14 +352,14 @@ be used in visual elements that use them. gui.run() ``` -You can take a look at the documentation of the [`dialog`](viselements/dialog.md) or -[`pane`](viselements/pane.md) to see how these *Partials* can be used in pages. +You can take a look at the documentation of the [`dialog`](../viselements/dialog.md) or +[`pane`](../viselements/pane.md) to see how these *Partials* can be used in pages. # Panes Modern user interfaces also provide small pages that pop out and be removed for temporary use, such as providing specific parameters for the application. Taipy lets -you create such elements using the [pane](viselements/pane.md) block. +you create such elements using the [pane](../viselements/pane.md) block. A pane can appear from any border of your page, next to or on top of the page, and disappears when the user clicks outside its area. @@ -408,7 +419,7 @@ In this example, *gui.user_status.x* is set to 1234 (as initialized in the appli *gui.user_status.info* is the string defined in the `on_status()` function. !!! note "Extended status" - If the [*extended_status*](configuration.md#p-extended_status) parameter is set to True, + If the [*extended_status*](../configuration.md#p-extended_status) parameter is set to True, the dictionary associated with the *gui* key is augmented with runtime information of the application, such as the version of the Taipy GUI package that is running, the version of the Python interpreter that is running the application, the list of the extension diff --git a/docs/manuals/gui/tgb-1-d.png b/docs/manuals/gui/tgb-1-d.png new file mode 100644 index 000000000..17a5756b9 Binary files /dev/null and b/docs/manuals/gui/tgb-1-d.png differ diff --git a/docs/manuals/gui/tgb-1-l.png b/docs/manuals/gui/tgb-1-l.png new file mode 100644 index 000000000..91e759eea Binary files /dev/null and b/docs/manuals/gui/tgb-1-l.png differ diff --git a/docs/manuals/gui/tgb-2-d.png b/docs/manuals/gui/tgb-2-d.png new file mode 100644 index 000000000..72b57f966 Binary files /dev/null and b/docs/manuals/gui/tgb-2-d.png differ diff --git a/docs/manuals/gui/tgb-2-l.png b/docs/manuals/gui/tgb-2-l.png new file mode 100644 index 000000000..8d657b06f Binary files /dev/null and b/docs/manuals/gui/tgb-2-l.png differ diff --git a/docs/manuals/gui/tgb-3-d.png b/docs/manuals/gui/tgb-3-d.png new file mode 100644 index 000000000..5a3e1d1ab Binary files /dev/null and b/docs/manuals/gui/tgb-3-d.png differ diff --git a/docs/manuals/gui/tgb-3-l.png b/docs/manuals/gui/tgb-3-l.png new file mode 100644 index 000000000..43d2b92e1 Binary files /dev/null and b/docs/manuals/gui/tgb-3-l.png differ diff --git a/docs/manuals/gui/tgb-5-d.png b/docs/manuals/gui/tgb-5-d.png new file mode 100644 index 000000000..79ddf0447 Binary files /dev/null and b/docs/manuals/gui/tgb-5-d.png differ diff --git a/docs/manuals/gui/tgb-5-l.png b/docs/manuals/gui/tgb-5-l.png new file mode 100644 index 000000000..6a8f05640 Binary files /dev/null and b/docs/manuals/gui/tgb-5-l.png differ diff --git a/docs/manuals/gui/viselements/charts/others.md b/docs/manuals/gui/viselements/charts/others.md index 17f48cb38..c334572e0 100644 --- a/docs/manuals/gui/viselements/charts/others.md +++ b/docs/manuals/gui/viselements/charts/others.md @@ -51,7 +51,7 @@ And the chart definition is the following: Here is the resulting chart: -![Styling a line chart](others1.png) + ### Multiple charts @@ -162,7 +162,7 @@ and longitude coordinates. Here is how this looks on the page: -![Plotting on a map](others-maps1.png) + ### Tracking selection diff --git a/docs/manuals/gui/viselements/file_download.md_template b/docs/manuals/gui/viselements/file_download.md_template index cbed6daf9..06c1b6859 100644 --- a/docs/manuals/gui/viselements/file_download.md_template +++ b/docs/manuals/gui/viselements/file_download.md_template @@ -4,7 +4,7 @@ The content to be sent to the user's browser can be a file, a URL, or any data s a buffer of bytes.
The content can be dynamically generated when the user requests it. -!!! Note "Image format" +!!! note "Image format" Note that if the content is provided as a buffer of bytes, it can be converted to image content if and only if you have installed the [`python-magic`](https://pypi.org/project/python-magic/) Python package (as well diff --git a/docs/manuals/gui/viselements/image.md_template b/docs/manuals/gui/viselements/image.md_template index be4236fbc..5819a3ec7 100644 --- a/docs/manuals/gui/viselements/image.md_template +++ b/docs/manuals/gui/viselements/image.md_template @@ -1,6 +1,6 @@ A control that can display an image. -!!! Note "Image format" +!!! note "Image format" Note that if the content is provided as a buffer of bytes, it can be converted to an image content if and only if you have installed the [`python-magic`](https://pypi.org/project/python-magic/) Python package (as well diff --git a/docs/manuals/gui/viselements/index.md b/docs/manuals/gui/viselements/index.md index e67d8bdd5..3ecb46fa5 100644 --- a/docs/manuals/gui/viselements/index.md +++ b/docs/manuals/gui/viselements/index.md @@ -8,7 +8,7 @@ There are two types of *Visual Elements*: Beside the generic controls provided in Taipy GUI and listed in [this section](controls.md), the `taipy` package come with a dedicated set of Taipy GUI controls that let users display and interact with [Taipy Core entities](../../core/entities/index.md). These controls are listed - in the [Core back-end controls](../corelements/index.md) section. + in the [Scenario Management controls](../controls.md#scenario-management-controls) section. - *Blocks* let you organize controls (or blocks) in pages to provide the best possible user experience. @@ -72,7 +72,7 @@ elements to be inserted in the resulting page. The most common use of this construct is to create controls. Taipy expects the control type name to appear between the two first vertical bar characters (as in `<|control|...}>`). -!!! important "Shortcut for the default property" +!!! note "Shortcut for the default property" If the first fragment text is not the name of a control type, Taipy will consider this fragment to be the default value for the default property of the control, whose type name must then appear as the second element. @@ -120,7 +120,7 @@ fragment similar to: If you set a property that a visual element does not recognize, it is ignored without any warning. -!!! important "Indentation and block elements: element tag identifiers" +!!! note "Indentation and block elements: element tag identifiers" Markdown depends heavily on text indentation to decide whether or not a new paragraph or section should be created.
When dealing with block elements to create sections on your page, you might be @@ -293,7 +293,7 @@ difficult to read. Something you can do about this is create a Python dictionary contains all the key-value pairs for your properties (name and value), then use the name of the variable that holds that dictionary as the value of the `properties` property. -!!! Example +!!! example Say your Markdown content needs the following control: `<|dialog|title=Select an item in the list|open={show_dialog}|labels=Cancel;Validate|page_id=page|close_label=Cancel|>` diff --git a/docs/manuals/gui/viselements/slider.md_template b/docs/manuals/gui/viselements/slider.md_template index 76a0a0e3f..5148e2b8b 100644 --- a/docs/manuals/gui/viselements/slider.md_template +++ b/docs/manuals/gui/viselements/slider.md_template @@ -124,7 +124,7 @@ Then only those values are accessible by the user: You can use a slider control to display multiple values and let users select each.
To achieve that, the [*value*](#p-value) property must be initially set to an array containing the initial values to reflect. The slider will have one knob for each value.
-When the user moves any of the knobs, the [`on_change`](../../callbacks.md#variable-value-change) +When the user moves any of the knobs, the [`on_change`](../callbacks.md#variable-value-change) callback is invoked with the variable value set to an array containing the new selection. Let's create an initial value for our slider: diff --git a/docs/manuals/index.md b/docs/manuals/index.md index 2cf8f0682..203c98bca 100644 --- a/docs/manuals/index.md +++ b/docs/manuals/index.md @@ -1,5 +1,3 @@ -# About Taipy's Manuals - The Taipy manuals are split into two categories: - [**User Manuals**](usermans/index.md): these manuals provide information on how to use different diff --git a/docs/manuals/refmans/index.md b/docs/manuals/refmans/index.md index 4e6a0a532..2f700fd51 100644 --- a/docs/manuals/refmans/index.md +++ b/docs/manuals/refmans/index.md @@ -1,3 +1,12 @@ # About Taipy's Reference Manuals -TODO +Taipy exposes different application programming interfaces (API) that can be used for different +purposes. + +- All the Python packages defined by Taipy (Community and Enterprise editions) are documented in + the [Python APIs](../reference/index.md) section. +- The REST API for Scenario Management is exposed in the [REST APIs](../reference_rest/index.md) + section. +- The Javascript library that can be used to extend the Taipy GUI element set is documented in the + [Typescript APIs](../reference_guiext/index.md) section. + diff --git a/docs/manuals/rest/index.md b/docs/manuals/rest/index.md index d2f8cb80b..9a0d0522c 100644 --- a/docs/manuals/rest/index.md +++ b/docs/manuals/rest/index.md @@ -1,79 +1,86 @@ # Taipy REST -The Taipy REST package is a python library made to provide a REST server on top of [Taipy Core](../about. -md#taipy-core). -The purpose is to automate the use of Taipy Core features by exposing REST APIs. +The Taipy REST package is a python library made to provide a REST server on top of +[Taipy Core](../core/index.md). The purpose is to automate the use of Taipy Core features by +exposing REST APIs. -The Taipy REST APIs allows users to create, read, update, run and remove Taipy entities (including cycles, scenarios, -sequences, tasks, jobs and data nodes) through REST APIs. For more details about Taipy entities, please refer to [Core -concepts documentation](../core/concepts/index.md). +The Taipy REST APIs allows users to create, read, update, run and remove Taipy entities +(including cycles, scenarios, sequences, tasks, jobs and data nodes) through REST APIs. For more +details about Taipy entities, please refer to +[Core concepts documentation](../core/concepts/index.md). -It is particularly useful when it comes to integrating a Taipy application in a more complex IT ecosystem. +It is particularly useful when it comes to integrating a Taipy application in a more complex IT +ecosystem. ## Running Taipy REST server To expose the Taipy REST APIs, the Taipy REST server must first be started. -1. Configure your Taipy Core application. For more details on Taipy Core configuration, please refer to the - [Core configuration documentation](../core/config/index.md). - -2. The REST server do not require any configuration in most of the use cases. However, as an advanced user, you may - want to configure your Taipy REST server. Indeed, Taipy REST server relies - on [Flask](https://flask.palletsprojects.com/en/2.2.x/#). The three following Flask parameters are exposed by Taipy: - - `testing` is a boolean parameter used to run the Flask application on testing mode. Default value is False. - - `env` is an optional string parameter used as the application environment. - - `secret_key` is an optional parameter used as the application server secret key.
-
- These parameters can be set using the `GlobalAppConfig^` properties. Here is an example: - ``` python - from taipy import Config - - Config.configure_global_app(testing=True, - env="production", - secret_key="5f352379324c22463451387a0aec5d2f") - ``` +1. Configure your Taipy Core application. For more details on Taipy Core configuration, please + refer to the [Core configuration documentation](../core/config/index.md). + +2. The REST server do not require any configuration in most of the use cases. However, as an + advanced user, you may want to configure your Taipy REST server. Indeed, Taipy REST server + relies on [Flask](https://flask.palletsprojects.com/en/2.2.x/#). The three following Flask + parameters are exposed by Taipy: + - `testing` is a boolean parameter used to run the Flask application on testing mode. + Default value is False. + - `env` is an optional string parameter used as the application environment. + - `secret_key` is an optional parameter used as the application server secret key.
+
+ These parameters can be set using the `GlobalAppConfig^` properties. Here is an example: + ``` python + from taipy import Config + + Config.configure_global_app(testing=True, + env="production", + secret_key="5f352379324c22463451387a0aec5d2f") + ``` 3. Finally, you can run Taipy REST server as follows: - ``` python - import taipy as tp - - rest_service = tp.Rest() - tp.run(rest_service) - ``` - Below is the output of the previous Python code execution. - ``` - * Serving Flask app 'taipy.rest.app' (lazy loading) - * Environment: None - * Debug mode: off - * Running on http://127.0.0.1:5000 (Press CTRL+C to quit) - ``` - -!!! Note "When running the Taipy REST server, you will also run `Core^`" + ``` python + import taipy as tp + + rest_service = tp.Rest() + tp.run(rest_service) + ``` + Below is the output of the previous Python code execution. + ``` + * Serving Flask app 'taipy.rest.app' (lazy loading) + * Environment: None + * Debug mode: off + * Running on http://127.0.0.1:5000 (Press CTRL+C to quit) + ``` + +!!! note "When running the Taipy REST server, you will also run `Core^`" !!! info "Running the REST service" + To run the Taipy REST service with the other Taipy services, please refer to the [taipy.run() function](../run-deploy/run/running_services.md) page. ## Using Taipy REST APIs -Once your Taipy REST server is up and running, the REST APIs are exposed. Any REST client can be used to make some -HTTP requests to the various APIs exposed. The exhaustive list of APIs is available on the -[REST API](../reference_rest/index.md) reference manual. +Once your Taipy REST server is up and running, the REST APIs are exposed. Any REST client can be +used to make some HTTP requests to the various APIs exposed. The exhaustive list of APIs is +available on the [REST API](../reference_rest/index.md) reference manual. -The following presents a simple usage example of a Taipy REST API. It shows how to retrieve all data nodes -using either the curl command line REST client or a python REST client (the `requests` package). +The following presents a simple usage example of a Taipy REST API. It shows how to retrieve all +data nodes using either the curl command line REST client or a python REST client (the +`requests` package). -!!! Example +!!! example === "Curl" ```shell curl -X GET https://localhost:5000/api/v1/datanodes/ ``` - In this example the REST server is exposing APIs on `localhost` on the port `5000`. To retrieve all data nodes, - we need to call the `datanodes` entry point without any parameter using the `GET` HTTP method. + In this example the REST server is exposing APIs on `localhost` on the port `5000`. To + retrieve all data nodes, we need to call the `datanodes` entry point without any + parameter using the `GET` HTTP method. - The output of the previous call is the list of all existing data nodes in `JSON` format. In the present - example, we have two data nodes returned as follows: + The output of the previous call is the list of all existing data nodes in `JSON` format. + In the present example, we have two data nodes returned as follows: ``` JSON [{ "last_edit_date": null, @@ -112,11 +119,12 @@ using either the curl command line REST client or a python REST client (the `req response = requests.get("https://localhost:5000/api/v1/datanodes/") ``` - In this example the REST server is exposing APIs on `localhost` on the port `5000`. To retrieve all data nodes, - we need to call the `datanodes` entry point without any parameter using the `GET` HTTP method. + In this example the REST server is exposing APIs on `localhost` on the port `5000`. To + retrieve all data nodes, we need to call the `datanodes` entry point without any + parameter using the `GET` HTTP method. - The output of the previous call is the list of all existing data nodes in `JSON` format. In the present - example, we have two data nodes returned as follows: + The output of the previous call is the list of all existing data nodes in `JSON` format. + In the present example, we have two data nodes returned as follows: ``` JSON [{ "last_edit_date": null, diff --git a/docs/manuals/run-deploy/deploy/azure.md b/docs/manuals/run-deploy/deploy/azure.md index 3f806261f..1bccb11d6 100644 --- a/docs/manuals/run-deploy/deploy/azure.md +++ b/docs/manuals/run-deploy/deploy/azure.md @@ -13,7 +13,7 @@ [Azure App Service](https://learn.microsoft.com/en-us/azure/app-service/) is a managed platform that simplifies web application deployment, scaling, and management. Azure Web App, a service within App Service, specializes in hosting and managing web applications. As a Python developer, you can leverage Azure Web App to quickly deploy and run your Python-based web applications in a scalable, hassle-free environment. -!!! Note +!!! note You can create Azure App Service and Azure Web App using Azure Portal, VS Code, Azure Tools extension pack, or Azure CLI. In this section, we focus on Azure CLI. diff --git a/docs/manuals/run-deploy/deploy/databricks/index.md b/docs/manuals/run-deploy/deploy/databricks/index.md index b8c8332b1..640b9332c 100644 --- a/docs/manuals/run-deploy/deploy/databricks/index.md +++ b/docs/manuals/run-deploy/deploy/databricks/index.md @@ -2,11 +2,11 @@ Databricks is a standard platform for data scientists and big data engineers. It can provide a web-based development environment connected to your data source within your cloud provider. Nevertheless, Databricks does not provide a direct path to developing a web application. This documentation will show you how to adapt your infrastructure so that you can create a Taipy application in your Databricks environment. -!!! Note +!!! note Taipy is currently only available with Databricks **Standard** runtimes. -!!! Warning +!!! warning We recommend using Databricks deployments for testing or demonstration purposes only. @@ -18,7 +18,7 @@ In the current section, we consider the following as prerequisites: - A Linux-based machine that can communicate with your local machine and Databricks. - [:material-arrow-right: Running a Taipy application](../../run/index.md) -!!! Note +!!! note If you don't have a Linux-based machine, you can use a cloud provider like Microsoft Azure to [create one](https://learn.microsoft.com/en-us/azure/virtual-machines/linux/quick-create-portal?tabs=ubuntu). @@ -61,7 +61,7 @@ In the end, the browser sends a request to Nginx on the Linux-based machine; Ngi Here is the technical architecture of the solution: ![Technical architecture](./images/technical-architecture.svg) -!!! Warning +!!! warning The Linux-based machine should be accessible from your network and from Databricks. @@ -102,7 +102,7 @@ Go to the "Apps" panel and select "Web Terminal". It opens a new tab with a shel In this shell, enter the following command, replacing `username` and `machine-ip` with your values: ```ssh -R 8080:127.0.0.1:5000 @``` -!!! Note +!!! note If your SSH authentication is based on certificates, remember to upload them on Databricks. diff --git a/docs/manuals/run-deploy/deploy/docker/development.md b/docs/manuals/run-deploy/deploy/docker/development.md index b3c891eee..5ff8d93fd 100644 --- a/docs/manuals/run-deploy/deploy/docker/development.md +++ b/docs/manuals/run-deploy/deploy/docker/development.md @@ -24,7 +24,7 @@ RUN pip install -r requirements.txt CMD python main.py ``` -!!! Note +!!! note If you are using a SQL database based on Microsoft SQL Server, you need to add the following commands before installing your application: diff --git a/docs/manuals/run-deploy/deploy/docker/production.md b/docs/manuals/run-deploy/deploy/docker/production.md index e677b8676..8a556f73e 100644 --- a/docs/manuals/run-deploy/deploy/docker/production.md +++ b/docs/manuals/run-deploy/deploy/docker/production.md @@ -44,7 +44,7 @@ ENTRYPOINT [ "gunicorn", "-k", "geventwebsocket.gunicorn.workers.GeventWebSocket CMD [ "
:" ] ``` -!!! Note +!!! note If you are using a SQL database based on Microsoft SQL Server, you need to add the following commands before creating the user: diff --git a/docs/manuals/run-deploy/deploy/heroku/index.md b/docs/manuals/run-deploy/deploy/heroku/index.md index 2c6db4fdf..3c0766857 100644 --- a/docs/manuals/run-deploy/deploy/heroku/index.md +++ b/docs/manuals/run-deploy/deploy/heroku/index.md @@ -5,7 +5,7 @@ and test applications for free. The following documentation allows quick deployments on this platform for sharing applications. -!!! important +!!! warning This documentation targets **test** and **development** contexts only. We recommend not to deploy applications in a production environment when sensitive data is involved. diff --git a/docs/manuals/run-deploy/deploy/linux/redhat.md b/docs/manuals/run-deploy/deploy/linux/redhat.md index b04c33b42..5697a9d3a 100644 --- a/docs/manuals/run-deploy/deploy/linux/redhat.md +++ b/docs/manuals/run-deploy/deploy/linux/redhat.md @@ -44,7 +44,7 @@ sudo mv `pwd`/.local/bin/uwsgi /usr/bin/uwsgi sudo restorecon /usr/bin/uwsgi ``` -!!! Note +!!! note If you are using a SQL database based on Microsoft SQL Server, you need to install your corresponding [Microsoft ODBC Driver for SQL Server](https://docs.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server). @@ -113,7 +113,7 @@ In our example, we store this application in the variable _web_app_ (see line 3) Make sure you upload this code on your targeted machine and install your dependencies with _pip_. -!!! important +!!! note The entry point filename and the app variable name are important for the proper configuration of the *uWSGI* web application server. Please, keep them as is or adapt the configuration. @@ -180,7 +180,7 @@ Then restart _Nginx_: sudo systemctl restart nginx ``` -!!! Note +!!! note This configuration is only for HTTP. If you need an HTTPS connection, please read the [Nginx documentation](https://nginx.org/en/docs/http/configuring_https_servers.html). diff --git a/docs/manuals/run-deploy/deploy/linux/ubuntu.md b/docs/manuals/run-deploy/deploy/linux/ubuntu.md index b2cdc2348..eda93b7db 100644 --- a/docs/manuals/run-deploy/deploy/linux/ubuntu.md +++ b/docs/manuals/run-deploy/deploy/linux/ubuntu.md @@ -27,7 +27,7 @@ sudo pip install uwsgi gevent sudo ln -s `pwd`/.local/bin/uwsgi /usr/bin/uwsgi ``` -!!! Note +!!! note If you are using a SQL database based on Microsoft SQL Server, you need to install your corresponding [Microsoft ODBC Driver for SQL Server](https://docs.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server). @@ -103,7 +103,7 @@ In our example, we store this application in the variable *web_app* (see line 3) Make sure you upload this code on your target machine and install your dependencies with *pip*. -!!! important "Entry point" +!!! note "Entry point" The entry point filename and the application variable name are important for the proper configuration of the *uWSGI* web application server. Please, keep them as is or adapt the configuration. diff --git a/docs/manuals/run-deploy/run/running_services.md b/docs/manuals/run-deploy/run/running_services.md index 1bed1d8b4..a363bd624 100644 --- a/docs/manuals/run-deploy/run/running_services.md +++ b/docs/manuals/run-deploy/run/running_services.md @@ -2,7 +2,7 @@ Taipy provides you three runnable services: Taipy GUI, Taipy REST, and Taipy Cor calling the method _run()_ from the service instance either `Gui^`, `Rest^`, or `Core^`. You can also use `taipy.run()` to run multiple service(s) together. -!!! important "Running from the main module" +!!! note "Running from the main module" As you can see in the following examples, the code to run a Taipy service is set within a `if` block checking if the special variable `__name__` equals to `"__main__"`. It's a standard boilerplate code that protects users from diff --git a/docs/manuals/studio/gui.md b/docs/manuals/studio/gui.md index a537d3ab0..154bc6597 100644 --- a/docs/manuals/studio/gui.md +++ b/docs/manuals/studio/gui.md @@ -2,7 +2,7 @@ The Taipy Studio extension leverages the Visual Studio Code text edition functionality to accelerate the definition of Taipy GUI pages with the -[Markdown syntax](../gui/pages.md#using-markdown): +[Markdown syntax](../gui/pages/index.md#using-markdown): - [IntelliSense](https://learn.microsoft.com/en-us/visualstudio/ide/using-intellisense) can be used in the context of page definition.
diff --git a/docs/manuals/usermans/index.md b/docs/manuals/usermans/index.md index 7c0562f36..6b944de80 100644 --- a/docs/manuals/usermans/index.md +++ b/docs/manuals/usermans/index.md @@ -1,24 +1,22 @@ -# About Taipy's User Manuals +This User Manual covers all the topics and concepts that you can find in Taipy. For each topic, +we are trying to provide as many examples as possible so that you as a Taipy user can perform a +specific task. -This User Manual covers all the topics and concepts that you can find in Taipy. -For each topic, we are trying to provide as many examples as possible so that -you as a Taipy user can perform a specific task. +If you are just starting with Taipy, you may want to look at the +[Getting Started](../../getting_started/index.md) in order to see a step-by-step example of a +complete Taipy application. -If you are just starting with Taipy, you may want to look at the -[Getting Started document](../../getting_started/installation.md) -in order to see a step-by-step example of a complete Taipy application. - -!!! important "Supported Python versions" +!!! note "Supported Python versions" Taipy requires **Python 3.8** or newer. -## Quick Access +# Quick Access These topics are the most visited ones, we thought you’d like to have a glance at them! -## Graphical User Interface (GUI) - `taipy.gui` +# Graphical User Interface (GUI) - `taipy.gui` The `taipy.gui^` package allows you to design an effective Graphic User Interface. It provides many interactive widgets, controls, and presentative elements to enhance the @@ -53,16 +51,14 @@ user’s experience. [:material-arrow-right: GUI User Manual](../gui/index.md) -## Taipy Core - `taipy.core` - -The `taipy.core^` package is a Python library designed to build powerful and customized data-driven back-end -applications. -It provides the necessary tools to help Python developers transform their algorithms into a complete -back-end application. +# Taipy Core - `taipy.core` -Taipy Core brings algorithm management to another level: algorithms are now connected to the end-user through -user-defined scenarios, interactive data, smart job orchestration, etc. +The `taipy.core^` package is a Python library designed to build powerful and customized +data-driven back-end applications. It provides the necessary tools to help Python developers +transform their algorithms into a complete back-end application. +Taipy Core brings algorithm management to another level: algorithms are now connected to the +end-user through user-defined scenarios, interactive data, smart job orchestration, etc. [:material-arrow-right: Definition of Taipy Core concepts](../core/concepts/index.md), @@ -70,15 +66,16 @@ user-defined scenarios, interactive data, smart job orchestration, etc. [:material-arrow-right: Description of Taipy Core entities](../core/entities/index.md) -## Taipy REST - `taipy.rest` +# Taipy REST - `taipy.rest` -The `taipy.rest` package allows you to access Taipy Core functionalities such as scenarios management, -sequences and task orchestration, data management, etc., through a dedicated REST API. -This package aims to provide a solution to easily integrate Taipy applications with other IT systems. -The API comes with multiple endpoints for you to work with Taipy Core conveniently and efficiently. +The `taipy.rest` package allows you to access Taipy Core functionalities such as scenarios +management, sequences and task orchestration, data management, etc., through a dedicated REST API. +This package aims to provide a solution to easily integrate Taipy applications with other IT +systems. The API comes with multiple endpoints for you to work with Taipy Core conveniently and +efficiently. [:material-arrow-right: Taipy REST User Manual](../rest/index.md) -## Deployment +# Deployment [:material-arrow-right: Running & Deploying section](../run-deploy/index.md) diff --git a/docs/migration.md b/docs/migration.md index a1c66dd72..4b1157b3d 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -4,50 +4,84 @@ hide: - navigation --- -This documentation page lists the migration paths of Taipy releases as they -were published. +This documentation page lists the migration paths of Taipy releases as they were published. # From 2.x to 3.0 -In Taipy GUI 3.0, the `on_action` callback signature was unified across all controls: the third -parameter (*action*) was dropped. The *payload* dictionary parameter that used to be in fourth -place is now in third place and contains an *action* key that is set to the action name if you used -to use *action*. +1. In Taipy GUI 3.0, the `on_action` callback signature was unified across all controls: the third + parameter (*action*) was dropped. The *payload* dictionary parameter that used to be in fourth + place is now in third place and contains an *action* key that is set to the action name if you + used to use *action*. + +2. In Taipy Core 3.0 we deprecated the `pipeline` concept in favor of + [sequence](./manuals/core/entities/sequence-mgt.md). This also means that `configure_pipeline` + from Taipy Config was removed, making it necessary to update your config code. Take for + instance the following config on `Taipy 2.4`: + + ```python title="config.py from Taipy 2.4 edition" + from taipy import Config + + # Omiting multiply_task_cfg creation + + pipeline_cfg = Config.configure_pipeline( + "pipeline_1", + task_configs=[multiply_task_cfg] + ) + + scenario_cfg = Config.configure_scenario( + "multiply_scenario", + pipeline_configs=[pipeline_cfg] + ) + ``` + + Now, `configure_scenario` takes task configs as parameter in place of pipeline configs, so to + update the config above to `Taipy 3.0` is just a matter of: + + ```python title="config.py from Taipy 3.0 edition" + from taipy import Config + + # Omiting multiply_task_cfg creation + + scenario_cfg = Config.configure_scenario( + "multiply_scenario", + task_configs=[multiply_task_cfg] + ) + ``` + + After migrating the code, we recommend that you take advantage of `Taipy CLI` + [migration tool](./manuals/cli/migrate-entities.md). + # From 2.0 to 2.1 -In Taipy version 2.1, the version management system has been introduced. For -applications created with a Taipy Core version ≤ 2.0, the first time it -runs with version 2.1 or later, no version exists, and so legacy entities are not -attached to any version. The overall principle is to create a version the first -time the application runs with Taipy 2.1 or later and to assign all the old entities -to this version. Depending on the mode used to run the application, -(Refer to [versioning documentation](manuals/core/versioning/index.md) -for details) we propose the following migration paths: +In Taipy version 2.1, the version management system has been introduced. For applications +created with a Taipy Core version ≤ 2.0, the first time it runs with version 2.1 or later, +no version exists, and so legacy entities are not attached to any version. The overall principle +is to create a version the first time the application runs with Taipy 2.1 or later and to assign +all the old entities to this version. Depending on the mode used to run the application, +(Refer to [versioning documentation](manuals/core/versioning/index.md) for details) we propose +the following migration paths: ## Using default or development mode -Please refer to the [Development mode](manuals/core/versioning/development_mode.md) +Please refer to the [Development mode](manuals/core/versioning/development_mode.md) documentation page for more details on how to run Taipy in development mode. -The first time you run the application with Taipy 2.1 or later, if you use the -_development_ mode which is the default mode, Taipy automatically creates an -_experiment_ version with the current configuration and assigns all legacy -entities to it. The version is named "LEGACY-VERSION". Depending on how you -want to handle legacy entities, you can now manage your newly created version -using the version management system. Please refer to the -[Version management system](manuals/core/versioning/index.md) documentation page -for more details. +The first time you run the application with Taipy 2.1 or later, if you use the _development_ +mode which is the default mode, Taipy automatically creates an _experiment_ version with the +current configuration and assigns all legacy entities to it. The version is named +"LEGACY-VERSION". Depending on how you want to handle legacy entities, you can now manage your +newly created version using the version management system. Please refer to the +[Version management system](manuals/core/versioning/index.md) documentation page for more details. ## Using experiment or production mode Please refer to the [Experiment mode](manuals/core/versioning/experiment_mode.md) or -[Production mode](manuals/core/versioning/experiment_mode.md) documentation pages -for more details on how to run Taipy in experiment or production mode. - -The first time you run the application with Taipy 2.1 or later, if you use -_experiment_ or _production_ mode, you can simply provide a version name to create -a new version. All legacy entities are automatically attached to this version. -You can now manage your newly created version using the version management system. -Please refer to the [Version management system](manuals/core/versioning/index.md) -documentation page for more details. +[Production mode](manuals/core/versioning/experiment_mode.md) documentation pages for more +details on how to run Taipy in experiment or production mode. + +The first time you run the application with Taipy 2.1 or later, if you use _experiment_ or +_production_ mode, you can simply provide a version name to create a new version. All legacy +entities are automatically attached to this version. You can now manage your newly created +version using the version management system. Please refer to the +[Version management system](manuals/core/versioning/index.md) documentation page for more details. diff --git a/docs/relnotes-legacy.md b/docs/relnotes-legacy.md index 2a4a509b7..35da1962b 100644 --- a/docs/relnotes-legacy.md +++ b/docs/relnotes-legacy.md @@ -1,16 +1,15 @@ --- +title: Release Notes for Legacy Taipy versions hide: - navigation --- -# Release Notes for Legacy Taipy versions - This is the list of changes to legacy major Taipy releases as they were published. The Release Notes for the latest major version of Taipy can be found in [this page](relnotes.md). -## Community edition: 2.3 +# Community edition: 2.3 Published on 2023-06. @@ -20,7 +19,7 @@ Published on 2023-06. [`taipy-core` 2.3](https://pypi.org/project/taipy-core/2.3.0/) and [`taipy-rest` 2.3](https://pypi.org/project/taipy-rest/2.3.0/) packages. -### New Features +## New Features
taipy
2.3.0 @@ -83,7 +82,7 @@ Published on 2023-06. - The configuration of a version can now be compared with another one by running `$ taipy manage-versions --compare-config ` from the CLI. -### Improvements and changes +## Improvements and changes
taipy
2.3.2 @@ -125,7 +124,7 @@ Published on 2023-06. the up-to-date duration of a data node. - Add support for SQLAlchemy 2.0 -### Significant bug fixes +## Significant bug fixes
taipy-gui
2.3.0 @@ -139,7 +138,7 @@ Published on 2023-06. of time.
See [issue #777](https://github.com/Avaiga/taipy-gui/issues/777). -### Deprecations +## Deprecations
taipy-core
2.3.2 @@ -158,7 +157,7 @@ Published on 2023-06. - `PipelineConfig` has been deprecated and will be combined with `ScenarioConfig^` in future updates. - `taipy.create_pipeline()` has been deprecated. -## Community edition: 2.2 +# Community edition: 2.2 Published on 2023-04. @@ -168,7 +167,7 @@ Published on 2023-04. [`taipy-core` 2.2](https://pypi.org/project/taipy-core/2.2.2/) and [`taipy-rest` 2.2](https://pypi.org/project/taipy-rest/2.2.1/) packages. -### New Features +## New Features
taipy-gui
2.2.0 @@ -182,7 +181,7 @@ Published on 2023-04. controls have a new property called *rebuild* that can be used if you need to entirely change the data they rely on, including their structure. -### Improvements and changes +## Improvements and changes
taipy-gui
2.2.0 @@ -206,7 +205,7 @@ Published on 2023-04. in an *iframe*.
See [issue #621](https://github.com/Avaiga/taipy-gui/issues/621). -### Significant bug fixes +## Significant bug fixes
taipy-gui
2.2.0 @@ -233,7 +232,7 @@ Published on 2023-04. To avoid conflict between engines, the default value of the _db_driver_ parameter in a SQL or a SQL table data node configuration has been removed. -## Studio: 1.0 +# Studio: 1.0 Published on 2023-02. @@ -254,7 +253,7 @@ It mainly provides: You can refer to the [Taipy Studio User Manual](manuals/studio/index.md) section for more information. -## Community edition: 2.1 +# Community edition: 2.1 Published on 2023-01. @@ -267,7 +266,7 @@ Published on 2023-01. Please refer to the [Migration page](./migration.md#from-2.0-to-2.1) for details on how to migrate from version older than 2.1. -### New Features +## New Features
taipy
2.1 @@ -323,7 +322,7 @@ details on how to migrate from version older than 2.1. - The **sql** _repository_type_ is now available on community edition to store Core entities in an SQL database. See [SQL storage section](./manuals/core/config/core-config.md). -### Improvements and changes +## Improvements and changes
taipy-gui
2.1.0 @@ -354,7 +353,7 @@ details on how to migrate from version older than 2.1. by either a Taipy task execution or an external factor. This behavior is limited to file-based data nodes: CSV, Excel, JSON, and pickle data nodes only. -### Significant bug fixes +## Significant bug fixes
taipy-core
2.1.2 @@ -363,7 +362,7 @@ details on how to migrate from version older than 2.1. from "openpyxl>=3.0.7,<4.0" to "openpyxl>=3.0.7,<3.1" to match the version used by [Modin](https://modin.readthedocs.io/en/stable/). -## Community edition: 2.0 +# Community edition: 2.0 Published on 2022-10. @@ -373,7 +372,7 @@ Published on 2022-10. [`taipy-core` 2.0](https://pypi.org/project/taipy-core/2.0.3/) and [`taipy-rest` 2.0](https://pypi.org/project/taipy-rest/2.0.0/) packages. -### New Features +## New Features
taipy-gui
2.0.0 @@ -416,7 +415,7 @@ Published on 2022-10. - The new `taipy-config` package was exposed to be used by any other Taipy package for configuration and logging. -### Improvements and changes +## Improvements and changes
taipy-gui
2.0.0 @@ -440,7 +439,7 @@ Published on 2022-10. - The messages of the various Exceptions that can be raised have been improved to help the users debug their applications. -### Significant bug fixes +## Significant bug fixes
taipy-gui
2.0.2 @@ -463,26 +462,26 @@ Published on 2022-10. - Do not update `last_edit_date` when a job fails or is abandoned. See [issue #366](https://github.com/Avaiga/taipy-core/issues/366). -### Deprecations +## Deprecations
taipy-core
2.0.0 - The field `*nb_of_workers*` within the Config has been deprecated in favor of `*max_nb_of_workers*`. -## Enterprise edition: 2.0 +# Enterprise edition: 2.0 Published on 2022-10. -### New Features +## New Features - SQLLite or MongoDB databases can now be used as alternatives to the filesystem to store Taipy entities. -### Improvements and changes +## Improvements and changes - Simplification of the authentication API. -## Community edition: 1.1 +# Community edition: 1.1 Published on 2022-06. @@ -492,7 +491,7 @@ Published on 2022-06. [`taipy-rest` 1.1](https://pypi.org/project/taipy-rest/1.1.0/) packages. -### Improvements and changes +## Improvements and changes
taipy-gui
1.1.3 @@ -540,7 +539,7 @@ Published on 2022-06. the number of times Taipy will retry in case of error. - Performance improvements when reading and writing entities. -### Significant bug fixes +## Significant bug fixes
taipy-gui
1.1.3 @@ -561,7 +560,7 @@ Published on 2022-06. - Taipy supports HTTPS via reverse proxies.
See [issue #263](https://github.com/Avaiga/taipy-gui/issues/263). -### Deprecations +## Deprecations
taipy-core
1.1.0 @@ -574,21 +573,23 @@ Published on 2022-06. - The _edition_in_progress_ attribute of data nodes is now deprecated.
_edit_in_progress_ must be used instead. -## Enterprise edition: 1.1 +# Enterprise edition: 1.1 + +!!! warning Published on 2022-06. This release contains all of [`taipy` 1.1](https://pypi.org/project/taipy/1.1.0/) as well as additional features. -### Features +## Features - User authentication. - Authorization checks for all entities. - Job recovery mechanism on application restart. - Page generation based on the user's identity. -## Community edition: 1.0 +# Community edition: 1.0 Published on 2022-04. @@ -597,7 +598,7 @@ Published on 2022-04. [`taipy-core` 1.0](https://pypi.org/project/taipy-core/1.0.3/) and [`taipy-rest` 1.0](https://pypi.org/project/taipy-rest/1.0.1/) packages. -### Features +## Features
taipy-gui
1.0.0 diff --git a/docs/relnotes.md b/docs/relnotes.md index 5d8c7af71..d0c952913 100644 --- a/docs/relnotes.md +++ b/docs/relnotes.md @@ -1,214 +1,223 @@ --- +title : Release Notes hide: - navigation --- -# Release Notes - This is the list of changes to Taipy releases as they were published. !!! note "Migration" - Please refer to the [Migration page](./migration.md) for potential migration paths for your applications - implemented on legacy Taipy versions. + Please refer to the [Migration page](./migration.md) for potential migration paths for your + applications implemented on legacy Taipy versions. !!! note "Legacy Releases" This page shows the changes that were made in the most recent major release of Taipy.
- If you are using a legacy version, please refer to the [Legacy Release Notes](relnotes-legacy.md) - page. + If you are using a legacy version, please refer to the + [Legacy Release Notes](relnotes-legacy.md) page. -## Community edition: 3.0 (Work in progress) +# Community edition: 3.0 (Work in progress) Not published yet. -### New Features +## New Features
taipy
3.0.0 -- Taipy application can now be run with the Taipy command-line interface (CLI) using the `taipy run` - command. For more information, refer to [Run application in Taipy CLI](./manuals/cli/run.md). +- Taipy application can now be run with the Taipy command-line interface (CLI) using the + `taipy run` command. For more information, refer to + [Run application in Taipy CLI](./manuals/cli/run.md).
taipy-gui
3.0.0 -- Builder API - TODO +- A new package holds the [*Page Builder API*](manuals/gui/page_builder.md): a set of classes that + let you define the pages for your application entirely with Python. - You can now update variables on all clients using the *shared variables* concept. See - the `Gui.add_shared_variable()^` and `State.dispatch()^` methods for details. + the `Gui.add_shared_variable()^` and `State.dispatch()^` methods for details. - You can now invoke a callback for all clients using the `broadcast_callback()^` function. -- The [`slider`](manuals/gui/viselements/slider.md) control can now handle several knobs, allowing - for range selection.
- Please check the [example](manuals/gui/viselements/slider.md##multi-selection) for more - information. +- The [`slider`](manuals/gui/viselements/slider.md) control can now handle several knobs, + allowing for range selection.
+ Please check the [example](manuals/gui/viselements/slider.md##multi-selection) for more + information. - The [`file_download`](manuals/gui/viselements/file_download.md) control now lets developers - generate the file content dynamically, at download time.
- Please check the [example](manuals/gui/viselements/file_download.md#dynamic-content) for more - information. + generate the file content dynamically, at download time.
+ Please check the [example](manuals/gui/viselements/file_download.md#dynamic-content) for more + information. - A new CSS class called *toggle-navbar* was added to the - [Stylekit](manuals/gui/styling/stylekit.md) to give a - [`toggle`](manuals/gui/viselements/toggle.md) control the aspect of a - [`navbar`](manuals/gui/viselements/navbar.md). + [Stylekit](manuals/gui/styling/stylekit.md) to give a + [`toggle`](manuals/gui/viselements/toggle.md) control the aspect of a + [`navbar`](manuals/gui/viselements/navbar.md). - The [`chart`](manuals/gui/viselements/chart.md) control now supports the - [*treemap*](manuals/gui/viselements/charts/treemap.md) and - [*waterfall*](manuals/gui/viselements/charts/waterfall.md) chart types. + [*treemap*](manuals/gui/viselements/charts/treemap.md) and + [*waterfall*](manuals/gui/viselements/charts/waterfall.md) chart types.
taipy-core
3.0.0 - A production version of a Taipy application can now be provided with **migration functions** to - automatically migrate entities and keep them compatible with previous versions.
- For more information, refer to [Production mode](./manuals/core/versioning/production_mode.md). + automatically migrate entities and keep them compatible with previous versions.
+ For more information, refer to [Production mode](./manuals/core/versioning/production_mode.md). - A `GLOBAL` scope data node can be created from a data node configuration calling - the new `taipy.create_global_data_node()^` method.
- For more information, refer to - [Create a data node](./manuals/core/entities/data-node-mgt.md#create-a-data-node). + the new `taipy.create_global_data_node()^` method.
+ For more information, refer to + [Create a data node](./manuals/core/entities/data-node-mgt.md#create-a-data-node). - A data node configuration can be built from an existing data node configuration. - For more information, refer to - [Configure a data node from another configuration](./manuals/core/config/data-node-config.md#configure-a-data-node-from-another-configuration). + For more information, refer to the documentation page on + [data node configuration](./manuals/core/config/data-node-config.md#configure-a-data-node-from-another-configuration). - A new class `Submittable^` models entities that can be submitted for execution. - It is an Abstract class instantiated by `Scenario^` and `Sequence^`; - It can be handy to use the new following `Submittable^` methods: - - * `Submittable.get_inputs()^` retrieves input data nodes of a `Submittable` entity; - * `Submittable.get_outputs()^` retrieves output data nodes of a `Submittable` entity; - * `Submittable.get_intermediate()^` retrieves intermediate data nodes of a `Submittable` entity; - * `Submittable.is_ready_to_run()^` checks if an entity is ready to be run; - * `Submittable.data_nodes_being_edited()^` retrieves data nodes that are being edited - of a `Submittable^` entity; -- New functions exposed by the `taipy` module: `taipy.is_deletable()^` checks if an entity can be deleted. - `taipy.exists()^` checks if an entity exists. + It is an Abstract class instantiated by `Scenario^` and `Sequence^`. + It can be handy to use the new following `Submittable^` methods: + + * `Submittable.get_inputs()^` retrieves input data nodes of a `Submittable` entity; + * `Submittable.get_outputs()^` retrieves output data nodes of a `Submittable` entity; + * `Submittable.get_intermediate()^` retrieves intermediate data nodes of a `Submittable` + entity; + * `Submittable.is_ready_to_run()^` checks if an entity is ready to be run; + * `Submittable.data_nodes_being_edited()^` retrieves data nodes that are being edited + of a `Submittable^` entity. + +- New functions exposed by the `taipy` module: + * `taipy.is_deletable()^` checks if an entity can be deleted; + * `taipy.exists()^` checks if an entity exists. - The encoding type of CSVDataNode and JSONDataNode can now be configured using the - *encoding* parameter. For more information, please refer to - [Configure a CSVDataNode](./manuals/core/config/data-node-config.md#csv) - and [Configure a JSONDataNode](./manuals/core/config/data-node-config.md#json) - sections. + *encoding* parameter. For more information, please refer to + [Configure a CSVDataNode](./manuals/core/config/data-node-config.md#csv) + and [Configure a JSONDataNode](./manuals/core/config/data-node-config.md#json) + sections.
taipy-template
3.0.0 - A new template named "scenario-management" is available. For more information on creating - a new Taipy application with the new "scenario-management" template, refer to - [Create a Taipy application from a specific template](./manuals/cli/create.md#from-a-specific-template). + a new Taipy application with the new "scenario-management" template, refer to the + documentation page on [templates](./manuals/cli/create.md#from-a-specific-template). -### Improvements and changes +## Improvements and changes
taipy-core
3.0.0 - :warning: The *action* parameter of the `on_action` callback was removed for every control.
- The signature of all *on_action()* callback functions are now unified to the following: + The signature of all *on_action()* callback functions are now unified to the following: - *state* (`State^`): the state of the client invoking that callback; - *id* (str): the identifier of the visual element that triggers that callback; - *payload* (dict): a dictionary that provides additional information to the callback.
- This dictionary now has the additional *action* key that is set to the action name. - This change not only impact the *on_action* callback of all controls that support it, but in - an exactly similar manner the following callback signatures: - - *on_range_change* in the [`chart`](manuals/gui/viselements/chart.md) control; - - *on_edit*, *on_add*, and *on_delete* in the [`table`](manuals/gui/viselements/table.md) - control; - - *on_close* in the [`pane`](manuals/gui/viselements/pane.md) block. + This dictionary now has the additional *action* key that is set to the action name. + This change not only impact the *on_action* callback of all controls that support it, + but in an exactly similar manner the following callback signatures: + - *on_range_change* in the [`chart`](manuals/gui/viselements/chart.md) control; + - *on_edit*, *on_add*, and *on_delete* in the [`table`](manuals/gui/viselements/table.md) + control; + - *on_close* in the [`pane`](manuals/gui/viselements/pane.md) block. - The `navigate()^` function has an additional parameter *params* that is used to add query - parameters to the requested URL. The query parameters can be retrieved in the `on_navigate` - callback. + parameters to the requested URL. The query parameters can be retrieved in the `on_navigate` + callback. - The *on_action* parameter of the `download()^` function can be a function and not just a function - name. + name. - Setting the *debug* parameter of `Gui.run()^` to True provides stack traces to be shown in the - console when exceptions occur in user code. + console when exceptions occur in user code.
taipy-core
3.0.0 -- A `ScenarioConfig^` graph is now created directly from `TaskConfig^` and - `DataNodeConfig^`. Consequently, `PipelineConfig` has been removed. For more - information, refer to [Configure a scenario](./manuals/core/config/scenario-config.md). -- The `Pipeline^` object has been removed and replaced by `Sequence^`. A sequence is - held by a `Scenario^` and represents a subset of its tasks than can be submitted - together independently of the other tasks of the scenario. For more information, - refer to `Scenario.add_sequence()^` and `Scenario.remove_sequence()^`. -- `Scope.PIPELINE` has been removed from `Scope^` values. -- The `root_folder`, `storage_folder`, `read_entity_retry`, `repository_type`, and `repository_properties` - attributes of the `GlobalAppConfig^` have been moved to the `CoreSection^`.
- Please refer to the [Core configuration page](manuals/core/config/core-config.md) for details. +- :warning: A `ScenarioConfig^` graph is now created directly from `TaskConfig^` and + `DataNodeConfig^`. Consequently, `PipelineConfig` has been removed. For more + information, refer to [Configure a scenario](./manuals/core/config/scenario-config.md). +- :warning: The `Pipeline` object has been removed and replaced by `Sequence^`. A sequence is + held by a `Scenario^` and represents a subset of its tasks than can be submitted + together independently of the other tasks of the scenario. For more information, + refer to `Scenario.add_sequence()^` and `Scenario.remove_sequence()^`. +- `Scope.PIPELINE` has been removed from possible `Scope^` values. +- The `root_folder`, `storage_folder`, `read_entity_retry`, `repository_type`, and + `repository_properties` attributes of the `GlobalAppConfig^` have been moved to the + `CoreSection^`.
+ Please refer to the [Core configuration page](manuals/core/config/core-config.md) for details. - The `clean_entities` attribute has been removed from the `CoreSection^`. Correspondingly, the - `--clean-entities` option has been removed from the version management CLI.
- To clean entities of a version, please run your application in development mode, or delete your - version with the `--delete` CLI option. For more information, refer to - [Taipy command-line interface](./manuals/cli/index.md) + `--clean-entities` option has been removed from the version management CLI.
+ To clean entities of a version, please run your application in development mode, or delete your + version with the `--delete` CLI option. For more information, refer to + [Taipy command-line interface](./manuals/cli/index.md) - The deprecated `nb_of_workers` attribute of the JobConfig has been removed. -- The deprecated `parent_id` attribute of a DataNode, Task, Pipeline, or Scenario entity, has been removed. -- The deprecated `last_edition_date` and `edition_in_progress` attributes of a DataNode entity have been removed. -- The deprecated `DataNode.lock_edition()` and `DataNode.unlock_edition()` methods have been removed. +- The deprecated `parent_id` attribute of a DataNode, Task, Pipeline, or Scenario entity, has + been removed. +- The deprecated `last_edition_date` and `edition_in_progress` attributes of a DataNode entity + have been removed. +- The deprecated `DataNode.lock_edition()` and `DataNode.unlock_edition()` methods have been + removed. - The deprecated `taipy.create_pipeline()` method has been removed. - Function `DataNode.track_edit` has been made public.
taipy-template
3.0.0 -- The default template also supports creating a multi-pages application with Core and Rest services. - These options are available when creating a new application from the template. +- The default template also supports creating a multi-pages application with Core and Rest + services. These options are available when creating a new application from the template. - The "multi-page-gui" template has been removed. Please use the default instead to create - a Taipy multi-pages application. + a Taipy multi-pages application. -### Significant bug fixes +## Significant bug fixes
taipy-gui
3.0.0 - The callback function set to the *on_action* parameter of the function `download()^` may - be called too early. It is now ensured to be invoked *after* the download operation is - performed.
- See [issue #916](https://github.com/Avaiga/taipy-gui/issues/916). + be called too early. It is now ensured to be invoked *after* the download operation is + performed.
+ See [issue #916](https://github.com/Avaiga/taipy-gui/issues/916). - Setting the [*properties*](manuals/gui/viselements/index.md#generic-properties) property of - a visual element as the returned value from a function may not succeed.
- See [issue #897](https://github.com/Avaiga/taipy-gui/issues/897). + a visual element as the returned value from a function may not succeed.
+ See [issue #897](https://github.com/Avaiga/taipy-gui/issues/897). - Variables imported by an `import *` directive are not handled properly in the state of - a callback defined in the importing module.
- See [issue #908](https://github.com/Avaiga/taipy-gui/issues/908). + a callback defined in the importing module.
+ See [issue #908](https://github.com/Avaiga/taipy-gui/issues/908). - The [`date`](manuals/gui/viselements/date.md) control does not use the *format* property if - *with_time* is not set.
- See [issue #909](https://github.com/Avaiga/taipy-gui/issues/909). -- The [`date`](manuals/gui/viselements/date.md) control uses the `datetime.date` type and does not - apply tiem zones if time is not involved.
- See [issue #895](https://github.com/Avaiga/taipy-gui/issues/895) and - [issue #923](https://github.com/Avaiga/taipy-gui/issues/923). -- Updating a [`chart`](manuals/gui/viselements/chart.md) control data may cause data congestion or - display flickering.
- See [issue #864](https://github.com/Avaiga/taipy-gui/issues/864) and - [issue #932](https://github.com/Avaiga/taipy-gui/issues/932). -- Selection in a [`chart`](manuals/gui/viselements/chart.md) with type *pie* type is not properly - handled.
- See [issue #919](https://github.com/Avaiga/taipy-gui/issues/919). -- Hover text doesn't show properly in a [`selector`](manuals/gui/viselements/selector.md) that is - crowded.
- See [issue #927](https://github.com/Avaiga/taipy-gui/issues/927). + *with_time* is not set.
+ See [issue #909](https://github.com/Avaiga/taipy-gui/issues/909). +- The [`date`](manuals/gui/viselements/date.md) control uses the `datetime.date` type and does + not apply time zones if time is not involved.
+ See [issue #895](https://github.com/Avaiga/taipy-gui/issues/895) and + [issue #923](https://github.com/Avaiga/taipy-gui/issues/923). +- Updating a [`chart`](manuals/gui/viselements/chart.md) control data may cause data congestion + or display flickering.
+ See [issue #864](https://github.com/Avaiga/taipy-gui/issues/864) and + [issue #932](https://github.com/Avaiga/taipy-gui/issues/932). +- Selection in a [`chart`](manuals/gui/viselements/chart.md) with type *pie* type is not + properly handled.
+ See [issue #919](https://github.com/Avaiga/taipy-gui/issues/919). +- Hover text doesn't show properly in a [`selector`](manuals/gui/viselements/selector.md) that + is crowded.
+ See [issue #927](https://github.com/Avaiga/taipy-gui/issues/927). - Options with a long text in a [`selector`](manuals/gui/viselements/selector.md) cannot be - deselected.
- See [issue #917](https://github.com/Avaiga/taipy-gui/issues/917). + deselected.
+ See [issue #917](https://github.com/Avaiga/taipy-gui/issues/917). - The [`table`](manuals/gui/viselements/toggle.md) control does not support undefined date values - from Pandas data frames.
- See [issue #886](https://github.com/Avaiga/taipy-gui/issues/886). + from Pandas data frames.
+ See [issue #886](https://github.com/Avaiga/taipy-gui/issues/886).
taipy-core
3.0.0 -- When running the Core service in development mode, changing the name of the function used by a task then running - the application again would raise an error.
- See [issue #743](https://github.com/Avaiga/taipy-core/issues/743). +- When running the Core service in development mode, changing the name of the function used by a + task then running the application again would raise an error.
+ See [issue #743](https://github.com/Avaiga/taipy-core/issues/743). -## Enterprise edition: 3.0 (Work in progress) +# Enterprise edition: 3.0 (Work in progress) Not published yet. This release contains all of [`taipy` 3.0](https://pypi.org/project/taipy/3.0.0) as well as additional features. -### New Features +## New Features -- Python functions including scenario management methods can be scheduled to run at a specific time using the new `taipy.Scheduler^` API. - For more information, refer to [Schedule a method](./manuals/core/scheduling/index.md). +- Python functions including scenario management methods can be scheduled to run at a specific + time using the new `taipy.Scheduler^` API. For more information, refer to + [Schedule a method](./manuals/core/scheduling/index.md). -### Improvements and changes +## Improvements and changes - The job recovery mechanism is now only available when the Core service is run. diff --git a/mkdocs.yml_template b/mkdocs.yml_template index 056179e8d..35e6250c4 100644 --- a/mkdocs.yml_template +++ b/mkdocs.yml_template @@ -8,9 +8,9 @@ repo_name: taipy copyright: © [YEAR] Avaiga nav: - "Install Taipy": - - installation/index.md + - "Install Taipy": installation/index.md - "Getting Started": - - getting_started/index.md + - "Getting Started": getting_started/index.md - "Knowledge Base": - "Knowledge Base": knowledge_base/index.md - "Tutorials": @@ -20,19 +20,15 @@ nav: - "1 - First Web page": knowledge_base/tutorials/understanding_gui/step_01/step_01.md - "2 - Visual elements": knowledge_base/tutorials/understanding_gui/step_02/step_02.md - "3 - Interactions": knowledge_base/tutorials/understanding_gui/step_03/step_03.md - - "4 - Charts": knowledge_base/tutorials/understanding_gui/step_04/step_04/index.md + - "4 - Charts": knowledge_base/tutorials/understanding_gui/step_04/step_04.md - "5 - Python expressions in properties": knowledge_base/tutorials/understanding_gui/step_05/step_05.md - "6 - Page layouts": knowledge_base/tutorials/understanding_gui/step_06/step_06.md - "7 - Multi-pages, navbars, and menus": knowledge_base/tutorials/understanding_gui/step_07/step_07.md - - "Scenario management Overview": - - "Scenario management Overview": knowledge_base/tutorials/scenario_management_overview/index.md - - "1 - Scenario config and run": knowledge_base/tutorials/scenario_management_overview/step_01/step_01.md - - "4 - Cycles": knowledge_base/tutorials/scenario_management_overview/step_04/step_04.md - - "5 - Scopes": knowledge_base/tutorials/scenario_management_overview/step_05/step_05.md - - "6 - Skipping tasks": knowledge_base/tutorials/scenario_management_overview/step_06/step_06.md - - "7 - Execution modes": knowledge_base/tutorials/scenario_management_overview/step_07/step_07.md - - "8 - Scenario comparison": knowledge_base/tutorials/scenario_management_overview/step_08/step_08.md - - "9 - Scenario subscription": knowledge_base/tutorials/scenario_management_overview/step_09/step_09.md + - "Scenario management Overview": knowledge_base/tutorials/scenario_management_overview/index.md + - "Cycles and Scopes": knowledge_base/tutorials/cycles_scopes/index.md + - "Job Execution mode": knowledge_base/tutorials/job_execution/index.md + - "Scenario Comparison": knowledge_base/tutorials/scenario_comparison/index.md + - "Scenario Subscription": knowledge_base/tutorials/scenario_subscription/index.md - "Build a complete application": - "Build a complete application": knowledge_base/tutorials/complete_application/index.md - "1 - Data visualization page": knowledge_base/tutorials/complete_application/step_01/step_01.md @@ -43,15 +39,15 @@ nav: - "Markdown Syntax": knowledge_base/tutorials/markdown_syntax.md - "Data Dashboard": knowledge_base/tutorials/data_dashboard.md - "Changing Line Types Using Charts": knowledge_base/tutorials/charts.md - - "Manage Multiple Graphical Pages": knowledge_base/tutorials/graphical_pages.md + - "Manage Multiple Pages": knowledge_base/tutorials/graphical_pages.md - "Partials in Taipy": knowledge_base/tutorials/partials.md - - "Manage Data Pipelines with Scenarios": knowledge_base/tutorials/data_pipelines.md - - "Data Nodes and Tasks": knowledge_base/tutorials/data_nodes.md + - "Scenario Management concepts": knowledge_base/tutorials/scenario_mgt_concepts.md + - "Submitting Scenario and Tasks": knowledge_base/tutorials/execution.md - "Demos": - "Demos": knowledge_base/demos/index.md - "Sales Dashboard": knowledge_base/demos/sales_dashboard.md - - "Tweet generation": knowledge_base/demos/tweet_generation.md - - "Face Recognition": knowledge_base/demos/face_recognition.md + - "Tweet Generation": knowledge_base/demos/tweet_generation.md + - "Real-time Face Recognition": knowledge_base/demos/face_recognition.md - "Sentiment Analysis": knowledge_base/demos/sentiment_analysis.md - "Optimize Bar Cut Sizes": knowledge_base/demos/bar_cutting.md - "Image Classification": knowledge_base/demos/image_classif.md @@ -59,27 +55,30 @@ nav: - "Production Planning": knowledge_base/demos/production_planning.md - "Stock Visualization": knowledge_base/demos/stock_visualization.md - "COVID Dashboard": knowledge_base/demos/covid_dashboard.md - - "Movie genre selector": knowledge_base/demos/movie_genre_selector.md + - "Movie Genre Selector": knowledge_base/demos/movie_genre_selector.md - "Tips and tricks": - "Tips and tricks": knowledge_base/tips/index.md + - "Scenarios": knowledge_base/tips/scenarios/index.md + - "Taipy Application on Colab with Ngrok": knowledge_base/tips/colab_with_ngrok/index.md - "Jupyter Notebooks": knowledge_base/tips/jupyter_notebooks/index.md - - "Skippable Tasks": knowledge_base/tips/skippable_tasks/index.md - - "Taipy Cloud": knowledge_base/tips/taipy_cloud_deploy/index.md - - "Stylekit": knowledge_base/tips/css_style_kit/index.md - - "Data Nodes": knowledge_base/tips/the_data_nodes/index.md - - "Using Tables": knowledge_base/tips/using_tables/index.md - - "Multi-page Application": knowledge_base/tips/multipage_application/index.md - "Long Running Callbacks": knowledge_base/tips/long_callbacks/index.md - - "Taipy Application on Colab with Ngrok": knowledge_base/tips/colab_with_ngrok/index.md - - "Scenarios": knowledge_base/tips/scenarios/index.md + - "Multi-page Application": knowledge_base/tips/multipage_application/index.md + - "Using Tables": knowledge_base/tips/using_tables/index.md + - "Data Nodes": knowledge_base/tips/the_data_nodes/index.md + - "Stylekit": knowledge_base/tips/css_style_kit/index.md + - "Skippable Tasks": knowledge_base/tips/skippable_tasks/index.md - "Callbacks in Taipy": knowledge_base/tips/the_on_change_callback/index.md + - "Taipy Cloud": knowledge_base/tips/taipy_cloud_deploy/index.md + - "Real-time data visualization": knowledge_base/tips/multithreading/index.md - "Manuals": - - manuals/index.md + - "About Taipy's Manuals": manuals/index.md - "User Manuals": - - manuals/usermans/index.md + - "About Taipy's User Manuals": manuals/usermans/index.md - Taipy GUI: - manuals/gui/index.md - - "Pages": manuals/gui/pages.md + - "Pages": + - manuals/gui/pages/index.md + - "Using code": manuals/gui/page_builder.md - "Visual Elements": - "Introduction to Visual Elements": manuals/gui/viselements/index.md - "Controls": manuals/gui/viselements/controls.md @@ -208,7 +207,7 @@ nav: - "Release Notes": relnotes.md - "Contributing": - "Contributing to Taipy": contributing/contributing.md - - "Contributors": credits/contributors.md + - "Contributors": contributing/contributors.md - "Code of conduct": contributing/code_of_conduct.md theme: name: material diff --git a/taipy_theme/assets/stylesheets/avaiga.css b/taipy_theme/assets/stylesheets/avaiga.css index 1eac3b0f1..a4124e4ca 100644 --- a/taipy_theme/assets/stylesheets/avaiga.css +++ b/taipy_theme/assets/stylesheets/avaiga.css @@ -17,11 +17,16 @@ --md-footer-fg-color--lighter: #fff; --md-default-border-color: hsla(var(--md-hue),50%,8%,0.1); + --md-accessory-color-alpha: #7A3DB8; + --md-accessory-color-beta: #22AED1; + --md-accessory-color-gamma: #FFC15E; + --md-accessory-color-delta: #8E1574; + --md-info-color: var(--md-accent-fg-color); - --md-example-color: var(--md-accent-fg-color--light); - --md-success-color: #3EA764; - --md-warning-color: #FAA916; - --md-error-color: #FF595E; + --md-example-color: var(--md-accessory-color-alpha); + --md-success-color: var(--md-accessory-color-beta); + --md-warning-color: var(--md-accessory-color-gamma); + --md-error-color: var(--md-accessory-color-delta); --admonition-color: var(--md-info-color); /* Typography */ @@ -43,6 +48,10 @@ --md-content-padding-y: 2rem; --md-sidebar-width: 16rem; --md-paper-shadow: 0 0 0 1px var(--md-default-border-color); + --md-paper-shadow-hover: 0 0 24px var(--md-default-fg-color--lighter); + --tp-content-card-padding: 1.5rem; + --tp-content-card-image-size: 7.5rem; + --tp-pill-shadow-active: 0 0 0 1px var(--md-primary-fg-color); /* Animations */ --transition-duration-base: 400ms; @@ -72,6 +81,12 @@ --md-hue: 270; } +@media screen and (max-width: 59.9375em){ + html{ + font-size: 100%; + } +} + .md-grid{ max-width: var(--md-grid-max-width); } @@ -179,8 +194,16 @@ align-items: center; } -/* ---------- ---------- ---------- MOBILE SIDEBAR (DRAWER) ---------- ---------- ---------- */ +/* ---------- ---------- ---------- SIDEBAR (DRAWER) ---------- ---------- ---------- */ +[dir=ltr] .md-sidebar__inner { + padding-right: calc(100% - 15rem); +} +[dir=rtl] .md-sidebar__inner { + padding-left: calc(100% - 15rem) +} + +/* ---------- ---------- ---------- MOBILE SIDEBAR (DRAWER) ---------- ---------- ---------- */ @media screen and (max-width: 76.1875em){ .md-sidebar__inner > .md-nav > .md-nav__title{ height: auto; @@ -318,6 +341,16 @@ font-size: var(--md-body-font-size--small); } +.tp-tag{ + display: inline-block; + vertical-align: middle; + color: var(--md-primary-fg-color); + font-size: 0.6rem; + font-family: monospace; + text-transform: uppercase; + letter-spacing: 0.1em; +} + /* ---------- ADMONITIONS ---------- */ .md-typeset .admonition{ @@ -396,6 +429,48 @@ a.ext-link::after{ display: flex; } +/* ---------- ---------- ---------- BUTTONS ---------- ---------- ---------- */ + +.tp-btn{ + margin-right: 0.4rem; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.4rem; + min-height: 2.5rem; + padding: 0.4rem 1rem; + background-color: var(--md-primary-fg-color); + border-radius: 50rem; + color: white !important; + font-size: 0.8rem; + font-weight: bold; + transition: background-color 0.3s, color 0.3s; +} + +.tp-btn--accent{ + background: var(--md-accent-fg-color); +} +.tp-btn--alpha{ + background: var(--md-accessory-color-alpha); +} +.tp-btn--beta{ + background: var(--md-accessory-color-beta); +} +.tp-btn--gamma{ + background: var(--md-accessory-color-gamma); +} +.tp-btn--delta{ + background: var(--md-accessory-color-delta); +} + +.tp-btn:hover{ + background-color: hsla(var(--md-hue),50%,15%,1); +} + +.tp-btn.ext-link::after{ + height: auto; +} + /* ---------- ---------- ---------- TOOLTIP ---------- ---------- ---------- */ .tp-tooltip{ @@ -454,6 +529,7 @@ a.tp-pill{ display: inline-flex; align-items: center; text-align: center; + gap: 4px; padding: 0.6em 1.5em; border-radius: 50rem; background: var(--md-paper-bg-color); @@ -467,6 +543,25 @@ a.tp-pill{ transform: translate(-50%, 0); } +.tp-pills-filter .tp-pill{ + cursor: pointer; +} + +.tp-pills-filter input{ + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + white-space: nowrap; + clip: rect(0 0 0 0); + clip-path: inset(50%); +} + +.tp-pills-filter input:checked + .tp-pill{ + color: var(--md-primary-fg-color); + box-shadow: var(--tp-pill-shadow-active); +} + .tp-pill:hover .tp-tooltip{ left: 50%; transform: translate(-50%, -0.5rem); @@ -478,23 +573,89 @@ a.tp-pill{ /* ---------- ---------- ---------- Content Cards ---------- ---------- ---------- */ +.tp-cards-list{ + margin-left: 0 !important; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.tp-cards-list li{ + margin-left: 0 !important; + list-style-type: none; +} + .tp-content-card{ flex: 0 0 100%; position: relative; display: flex; flex-direction: column; + gap: 0.5rem; justify-content: flex-start; align-items: stretch; - padding: 1.25em; - border-radius: 0.5em; + padding: var(--tp-content-card-padding); + border-radius: 0.8rem; background: var(--md-paper-bg-color); color: var(--md-default-fg-color); overflow: hidden; font-size: var(--md-body-font-size--small); box-shadow: var(--md-paper-shadow); } + .tp-content-card[href]{ color: var(--md-default-fg-color); + transition: color 0.3s ease, background-color 0.3s ease, box-shadow 0.3s ease; +} + +.tp-content-card[href]:hover{ + color: var(--md-default-fg-color); + box-shadow: var(--md-paper-shadow-hover); +} + +.tp-content-card--horizontal{ + flex-direction: row; + align-items: flex-start; + gap: 1rem; +} + +.tp-content-card--small{ + --tp-content-card-padding: 1rem; +} + +.tp-content-card.tp-content-card--primary{ + background: var(--md-primary-fg-color); +} +.tp-content-card.tp-content-card--accent{ + background: var(--md-accent-fg-color); +} +.tp-content-card.tp-content-card--alpha{ + background: var(--md-accessory-color-alpha); +} +.tp-content-card.tp-content-card--beta{ + background: var(--md-accessory-color-beta); +} +.tp-content-card.tp-content-card--gamma{ + background: var(--md-accessory-color-gamma); +} +.tp-content-card.tp-content-card--delta{ + background: var(--md-accessory-color-delta); +} +.tp-content-card.tp-content-card--primary, +.tp-content-card.tp-content-card--accent, +.tp-content-card.tp-content-card--alpha, +.tp-content-card.tp-content-card--beta, +.tp-content-card.tp-content-card--gamma, +.tp-content-card.tp-content-card--delta{ + color: white +} + +.tp-content-card.tp-content-card--primary:hover, +.tp-content-card.tp-content-card--accent:hover, +.tp-content-card.tp-content-card--alpha:hover, +.tp-content-card.tp-content-card--beta:hover, +.tp-content-card.tp-content-card--gamma:hover, +.tp-content-card.tp-content-card--delta:hover{ + color: white } .tp-content-card + .tp-content-card{ @@ -508,28 +669,55 @@ a.tp-pill{ .tp-content-card :first-child{ margin-top: 0; } -.md-typeset .tp-content-card > *{ - margin-bottom: 0; -} -.md-typeset .tp-content-card > * + *{ - margin-top: 1rem; -} .tp-content-card-header{ - margin-bottom: 1.5rem; display: flex; align-items: center; - gap: 1rem; + gap: 0.5rem; +} + +.tp-content-card-header > *{ + margin-bottom: 0; +} + +.tp-content-card-body{ + flex: 1; + display: flex; + flex-direction: column; + gap: 0.25rem; } -.tp-content-card h3{ +.tp-content-card .tp-content-card-body > *{ + margin: 0; +} + +.tp-content-card h3, +.tp-content-card h4, +.tp-content-card h5{ margin: 0; flex: 1 1 0; min-width: 0; + color: currentColor; } .tp-content-card-icon{ margin-top: 0; + height: 4rem; +} +.tp-content-card--small .tp-content-card-icon{ + height: 2rem; +} + +.tp-content-card-image{ + margin-top: 0; + width: var(--tp-content-card-image-size); + height: var(--tp-content-card-image-size) !important; + border-radius: 0.4rem; + box-shadow: var(--md-paper-shadow); + object-fit: cover; +} +.tp-content-card--small .tp-content-card-image{ + --tp-content-card-image-size: 6rem; } .tp-content-card-readmore{ @@ -702,6 +890,10 @@ a.md-content__button{ color: var(--md-primary-fg-color); } +.tp-separator{ + border-bottom: var(--md-default-border-color); +} + /* ---------- ---------- ---------- Breadcrumbs ---------- ---------- ---------- */ .tp-bc { margin-left: 0.8rem; diff --git a/taipy_theme/assets/stylesheets/partials/_grid.css b/taipy_theme/assets/stylesheets/partials/_grid.css index e35bb0582..bcfd56757 100644 --- a/taipy_theme/assets/stylesheets/partials/_grid.css +++ b/taipy_theme/assets/stylesheets/partials/_grid.css @@ -11,6 +11,15 @@ gap: var(--tp-grid-gutter); } +ul.tp-row{ + margin-left: 0 !important; + display: flex !important; +} +ul.tp-row li{ + margin-left: 0 !important; + list-style: none !important; +} + .tp-row--gutter-sm{ --tp-grid-gutter: 1rem; } diff --git a/tools/_setup_generation/setup.py b/tools/_setup_generation/setup.py index 9a400bafc..b4dba7dc3 100644 --- a/tools/_setup_generation/setup.py +++ b/tools/_setup_generation/setup.py @@ -2,6 +2,7 @@ from datetime import datetime import re import shutil +import sys from typing import List @@ -19,13 +20,16 @@ def __init__(self, root_dir: str, steps: List["SetupStep"]): self.docs_dir = self.root_dir + "/docs" self.manuals_dir = self.docs_dir + "/manuals" self.tools_dir = self.root_dir + "/tools" - # self.requested_steps can be used to specify which steps should - # be performed. - # Until there are command line options to control this, - # you can initialize this field with a list of step ids. - # At this time, we have: "getting_started", "refman", "rest", "viselements" - # and "guiext". + # self.requested_steps, if not None, indicates which steps should be performed. self.requested_steps = None + if len(sys.argv) > 1: + self.requested_steps = [] + for step_id in sys.argv[1:]: + if not [step for step in steps if step_id == step.get_id()]: + raise SystemError(f"FATAL - '{step_id}' is not a valid step identifier") + for step in steps: + if step.get_id() in sys.argv[1:]: + self.requested_steps.append(step) self.mkdocs_yml_template_content = None self.MKDOCS_YML_PATH = self.root_dir + "/mkdocs.yml" self.MKDOCS_YML_TEMPLATE_PATH = self.MKDOCS_YML_PATH + "_template" @@ -37,7 +41,7 @@ def __init__(self, root_dir: str, steps: List["SetupStep"]): ) self.steps = [] for step in steps: - if self.requested_steps is None or step.get_id() in self.requested_steps: + if not self.requested_steps or step in self.requested_steps: self.steps.append(step) step.enter(self) else: diff --git a/tools/_setup_generation/step_contributors.py b/tools/_setup_generation/step_contributors.py index d56b7d0ec..2266c6d4c 100644 --- a/tools/_setup_generation/step_contributors.py +++ b/tools/_setup_generation/step_contributors.py @@ -28,7 +28,7 @@ def __init__(self): self.TEMPLATE_SUFFIX = "_template" def enter(self, setup: Setup): - self.PATH = os.path.join(setup.docs_dir, "credits", "contributors.md") + self.PATH = os.path.join(setup.docs_dir, "contributing", "contributors.md") def get_id(self) -> str: return "contributors" @@ -137,6 +137,5 @@ def __get(self, url, with_token=True, ignore404:bool = False): else: return requests.get(url) - def exit(self, setup: Setup): pass diff --git a/tools/_setup_generation/step_viselements.py b/tools/_setup_generation/step_viselements.py index 51341b151..3ffcaab09 100644 --- a/tools/_setup_generation/step_viselements.py +++ b/tools/_setup_generation/step_viselements.py @@ -12,12 +12,15 @@ # [VISELEMENTS_DIR_PATH]/[controls|blocks].md_template # are also completed with generated table of contents. # ################################################################################ -from .setup import Setup, SetupStep import json import os import re +import sys from typing import Dict, List, Optional +from .setup import Setup, SetupStep +from io import StringIO + class VisElementsStep(SetupStep): DEFAULT_PROPERTY = "default_property" PROPERTIES = "properties" @@ -29,7 +32,7 @@ def get_id(self) -> str: def get_description(self) -> str: return "Extraction of the visual elements documentation" - + def enter(self, setup: Setup): self.VISELEMENTS_DIR_PATH = setup.manuals_dir + "/gui/viselements" self.CORELEMENTS_DIR_PATH = setup.manuals_dir + "/gui/corelements" @@ -45,15 +48,20 @@ def enter(self, setup: Setup): raise FileNotFoundError( f"FATAL - Could not read {template_path} Markdown template" ) - self.charts_home_html_path = self.VISELEMENTS_DIR_PATH + "/charts/home.html_fragment" + self.charts_home_html_path = ( + self.VISELEMENTS_DIR_PATH + "/charts/home.html_fragment" + ) if not os.access(self.charts_home_html_path, os.R_OK): raise FileNotFoundError( f"FATAL - Could not read {self.charts_home_html_path} html fragment" ) + # Load Taipy GUI and Taipy elements # ----------------------------------------------------------- # Load elements, check basic features and resolve inheritance - def load_elements(self, elements_json_path: str, prefix: str, doc_pages_path: str) -> None: + def load_elements( + self, elements_json_path: str, prefix: str, doc_pages_path: str + ) -> None: with open(elements_json_path) as elements_json_file: loaded_elements = json.load(elements_json_file) @@ -69,7 +77,10 @@ def load_elements(self, elements_json_path: str, prefix: str, doc_pages_path: st f"FATAL - Duplicate element type '{element_type}' in {elements_json_path}" ) element_desc = element[1] - if not __class__.PROPERTIES in element_desc and not __class__.INHERITS in element_desc: + if ( + not __class__.PROPERTIES in element_desc + and not __class__.INHERITS in element_desc + ): raise ValueError( f"FATAL - No properties in element type '{element_type}' in {elements_json_path}" ) @@ -90,13 +101,17 @@ def load_elements(self, elements_json_path: str, prefix: str, doc_pages_path: st element_desc[__class__.DEFAULT_PROPERTY] = default_property # Resolve inheritance - def merge(element_desc, parent_element_desc, default_property: str) -> Optional[str]: + def merge( + element_desc, parent_element_desc, default_property: str + ) -> Optional[str]: element_properties = element_desc.get(__class__.PROPERTIES, []) element_property_names = [p[__class__.NAME] for p in element_properties] for property in parent_element_desc.get(__class__.PROPERTIES, []): property_name = property[__class__.NAME] if property_name in element_property_names: - element_property = element_properties[element_property_names.index(property_name)] + element_property = element_properties[ + element_property_names.index(property_name) + ] for n in ["type", "default_value", "doc"]: if not n in element_property and n in property: element_property[n] = property[n] @@ -104,9 +119,12 @@ def merge(element_desc, parent_element_desc, default_property: str) -> Optional[ element_property_names.append(property_name) element_properties.append(property) element_desc[__class__.PROPERTIES] = element_properties - if not default_property and parent_element_desc.get(__class__.DEFAULT_PROPERTY, False): + if not default_property and parent_element_desc.get( + __class__.DEFAULT_PROPERTY, False + ): default_property = parent_element_desc[__class__.DEFAULT_PROPERTY] return default_property + def resolve_inheritance(element_desc): if parent_types := element_desc.get(__class__.INHERITS, None): del element_desc[__class__.INHERITS] @@ -115,20 +133,35 @@ def resolve_inheritance(element_desc): for parent_type in parent_types: parent_desc = self.elements[parent_type] resolve_inheritance(parent_desc) - default_property = merge(element_desc, parent_desc, default_property) + default_property = merge( + element_desc, parent_desc, default_property + ) if original_default_property != default_property: element_desc[__class__.DEFAULT_PROPERTY] = default_property + for element_desc in self.elements.values(): - resolve_inheritance( element_desc) + resolve_inheritance(element_desc) self.elements = {} self.categories = {} - load_elements(self, setup.root_dir + "/taipy/gui/viselements.json", "", self.VISELEMENTS_DIR_PATH) - load_elements(self, setup.root_dir + "/taipy/gui_core/viselements.json", "core_", self.CORELEMENTS_DIR_PATH) + load_elements( + self, + setup.root_dir + "/taipy/gui/viselements.json", + "", + self.VISELEMENTS_DIR_PATH, + ) + load_elements( + self, + setup.root_dir + "/taipy/gui_core/viselements.json", + "core_", + self.CORELEMENTS_DIR_PATH, + ) # Check that documented elements have a default property and a doc file, # and that their properties have the mandatory settings. - for category, element_type in [(c, e) for c,elts in self.categories.items() for e in elts]: + for category, element_type in [ + (c, e) for c, elts in self.categories.items() for e in elts + ]: if category == "undocumented": continue element_desc = self.elements[element_type] @@ -140,7 +173,7 @@ def resolve_inheritance(element_desc): raise ValueError( f"FATAL - No properties for element type '{element_type}'" ) - template_path = f"{element_desc['doc_path']}/{element_type}.md_template" + template_path = f"{element_desc['doc_path']}/{element_type}.md_template" if not os.access(template_path, os.R_OK): raise FileNotFoundError( f"FATAL - Could not find template doc file for element type '{element_type}' at {template_path}" @@ -164,7 +197,9 @@ def generate_pages(self, category: str, md_path: str) -> None: with open(f"{md_path}_template") as template_file: md_template = template_file.read() if not md_template: - raise FileNotFoundError(f"FATAL - Could not read {md_path}_template markdown template") + raise FileNotFoundError( + f"FATAL - Could not read {md_path}_template markdown template" + ) prefixes = set([desc["prefix"] for desc in self.elements.values()]) toc = {} for prefix in prefixes: @@ -185,6 +220,7 @@ def generate_element_doc(element_type: str, element_desc: Dict, prefix: str): f"Couldn't locate first paragraph in documentation for element '{element_type}'" ) first_documentation_paragraph = match.group(1) + element_desc['short_doc'] = first_documentation_paragraph # Build properties table properties_table = """ @@ -203,18 +239,30 @@ def generate_element_doc(element_type: str, element_desc: Dict, prefix: str): STAR = "(★)" default_property_name = element_desc[__class__.DEFAULT_PROPERTY] # Convert properties array to a dict - property_descs = { p["name"]: p for p in element_desc[__class__.PROPERTIES]} - for property_name in [default_property_name] + list(filter(lambda x: x != default_property_name, property_descs.keys())): + property_descs = {p["name"]: p for p in element_desc[__class__.PROPERTIES]} + for property_name in [default_property_name] + list( + filter(lambda x: x != default_property_name, property_descs.keys()) + ): property_desc = property_descs[property_name] - name = property_desc[__class__.NAME] - type = property_desc["type"] - default_value = property_desc.get("default_value", None) - doc = property_desc.get("doc", None) + name = property_desc[__class__.NAME] + type = property_desc["type"] + if m := re.match(r"dynamic\((.*?)\)", type): + type = f"{m[1]}
dynamic" + elif m := re.match(r"indexed\((.*?)\)", type): + type = f"{m[1]}
indexed" + else: + type = f"{type}" + default_value = property_desc.get("default_value", None) + doc = property_desc.get("doc", None) if not default_value: - default_value = "Required" if property_desc.get("required", False) else "" + default_value = ( + "Required" + if property_desc.get("required", False) + else "" + ) full_name = f"]+>', '', name)}\">" if name == default_property_name: - full_name += f"{name}
{STAR}" + full_name += f'{name}{STAR}' else: full_name += f"{name}" properties_table += ( @@ -241,11 +289,13 @@ def generate_element_doc(element_type: str, element_desc: Dict, prefix: str): f"Couldn't locate first header in documentation for element '{element_type}'" ) before_properties = match.group(1) - after_properties = match.group(2)+element_documentation[match.end() :] + after_properties = match.group(2) + element_documentation[match.end() :] # Chart hook if element_type == "chart": - values = self.chart_page_hook(element_documentation, before_properties, after_properties) + values = self.chart_page_hook( + element_documentation, before_properties, after_properties + ) before_properties = values[0] after_properties = values[1] @@ -259,7 +309,11 @@ def generate_element_doc(element_type: str, element_desc: Dict, prefix: str): ) e = element_type # Shortcut d = "../corelements/" if prefix == "core_" else "" - s = " style=\"font-size: .8em;\"" if e == "scenario_selector" or e == "data_node_selector" else "" + s = ( + ' style="font-size: .8em;"' + if e == "scenario_selector" or e == "data_node_selector" + else "" + ) return ( f'\n' + f"{e}\n" @@ -279,22 +333,126 @@ def generate_element_doc(element_type: str, element_desc: Dict, prefix: str): with open(md_path, "w") as md_file: for prefix in prefixes: - md_template = md_template.replace(f"[{prefix}TOC]", toc[prefix]+"\n") + md_template = md_template.replace( + f"[{prefix}TOC]", toc[prefix] + "\n" + ) md_file.write(md_template) + def generate_builder_api(self) -> None: + separator = "# Generated code for Page Builder" + py_file = "taipy/gui/builder/__init__.py" + py_content = None + with open(py_file, "r") as file: + py_content = file.read() + # Remove generated code + if m := re.search(f"\\n*{separator}", py_content): + py_content = py_content[:m.start(0)+1] + + def generate(self, category, base_class: str) -> str: + + element_types = self.categories[category] + def build_doc(property, desc, indent: int): + type = desc['type'] + dynamic = "" + dynamic_re = re.match(r"^dynamic\(\s*(.*)\s*\)$", type) + if False and dynamic_re: + type = dynamic_re[1] + dynamic = " (dynamic)" + doc = "" + if "doc" in desc: + doc = str(desc["doc"]).replace("\n", f'\n{(indent+4)*" "}').replace("
", f'
\n{(indent+4)*" "}') + default_value = f'{desc["default_value"]}' if "default_value" in desc else "" + if m := re.match(r"^(.*?)$", default_value): + default_value = f"\"{m[1]}\"" + elif m := re.match(r"^`(.*?)`$", default_value): + default_value = f"{m[1]}" + elif default_value == "scatter" or default_value == "lines+markers": + default_value = f"\"{default_value}\"" + if default_value: + try: + x = eval(default_value) + except: + raise SyntaxError(f"Default value for property '{property}' of element '{element_type}' is not a valid Python expression ({default_value})") + return (f"{property}={default_value if default_value else 'None'}, ", + f"{indent*' '}{desc['name']} ({type}){dynamic}: {doc}\n") + + template = f""" + +class [element_type]({base_class}): + '''[short_doc] + + This class represents the [control_or_block] documented in the [element_md_page] section. + ''' + _ELEMENT_NAME: str + def __init__(self, [arguments]) -> None: + '''Create a new `[element_type]` element. + + Arguments: + [arguments_doc] + ''' + ... +""" + + buffer = StringIO() + docline_in_template = next(l for l in template.splitlines() if l.lstrip().startswith("[arguments_doc]")) + doc_indent = len(docline_in_template) - len(docline_in_template.lstrip()) + + for element_type in element_types: + desc = self.elements[element_type] + properties = desc["properties"] + default_prop = next( + p for p in properties if p["name"] == desc["default_property"] + ) + doc = build_doc(default_prop['name'], default_prop, doc_indent) + arguments = doc[0] + arguments_doc = doc[1] + for property in properties: + property_name = property["name"] + if property_name != desc["default_property"] and not "[" in property_name: + doc = build_doc(property_name, property, doc_indent) + arguments += doc[0] + arguments_doc += doc[1] + # Process short doc + short_doc = desc["short_doc"] + if m := re.search(r"(\[`(\w+)`\]\()\2\.md\)", short_doc): + short_doc = short_doc[:m.start()]+f"{m[1]}../gui/viselements/{m[2]}.md)"+short_doc[m.end():] + # Link to element doc page + element_md_location = "corelements" if desc["prefix"] == "core_" else "viselements" + element_md_page = f"[`{element_type}`](../gui/{element_md_location}/{element_type}.md)" + buffer.write(template.replace("[element_type]", element_type) + .replace("[element_md_page]", element_md_page) + .replace("[arguments]", arguments) + .replace("[short_doc]", short_doc) + .replace("[control_or_block]", "control" if category=="controls" else "block") + .replace(" "*doc_indent+"[arguments_doc]\n", arguments_doc)) + s = buffer.getvalue() + return buffer.getvalue() + + with open(py_file, "wt") as file: + file.write(py_content) + file.write(f"\n\n{separator}\n\n") + file.write(f"from ._element import _Block, _Control\n\n") + file.write(generate(self, "controls", "_Control")) + file.write(generate(self, "blocks", "_Block")) + def setup(self, setup: Setup) -> None: self.generate_pages("controls", self.controls_path) self.generate_pages("blocks", self.blocks_path) + self.generate_builder_api() # Special case for charts: we want to insert the chart gallery that is stored in the # file whose path is in self.charts_home_html_path # This should be inserted before the first level 1 header - def chart_page_hook(self, element_documentation: str, before: str, after: str) -> tuple[str, str]: + def chart_page_hook( + self, element_documentation: str, before: str, after: str + ) -> tuple[str, str]: with open(self.charts_home_html_path, "r") as html_fragment_file: chart_gallery = html_fragment_file.read() # The chart_gallery begins with a comment where all sub-sections # are listed. - SECTIONS_RE = re.compile(r"^(?:\s*)", re.MULTILINE | re.DOTALL) + SECTIONS_RE = re.compile( + r"^(?:\s*)", re.MULTILINE | re.DOTALL + ) match = SECTIONS_RE.match(chart_gallery) if not match: raise ValueError( @@ -308,9 +466,14 @@ def chart_page_hook(self, element_documentation: str, before: str, after: str) - if match: chart_sections += f"- [{match.group(2)}](charts/{match.group(1)}.md)\n" - match = re.match(r"(^.*?)(?:\n#\s+)", element_documentation, re.MULTILINE | re.DOTALL) + match = re.match( + r"(^.*?)(?:\n#\s+)", element_documentation, re.MULTILINE | re.DOTALL + ) if not match: raise ValueError( f"Couldn't locate first header1 in documentation for element 'chart'" ) - return (match.group(1) + chart_gallery + before[match.end() :], after + chart_sections) + return ( + match.group(1) + chart_gallery + before[match.end() :], + after + chart_sections, + ) diff --git a/tools/postprocess.py b/tools/postprocess.py index 1dbf9f84e..fe2d45bf6 100644 --- a/tools/postprocess.py +++ b/tools/postprocess.py @@ -83,7 +83,9 @@ def remove_dummy_h3(content: str, ids: Dict[str, str]) -> str: def on_post_build(env): - "Post-build actions for Taipy documentation" + """ + Post-build actions for Taipy documentation + """ log = logging.getLogger("mkdocs") site_dir = env.conf["site_dir"] @@ -380,7 +382,7 @@ def on_post_build(env): html_content = new_content + html_content[last_location:] # Rename the GUI Extension API type aliases - if "reference_guiext" in filename: + elif "reference_guiext" in filename: for in_out in [("TaipyAction", "Action", "../interfaces/Action"), ("TaipyContext", "Context", "#context")]: LINK_RE = re.compile(f"{in_out[0]}") @@ -431,6 +433,34 @@ def on_post_build(env): + article_match.group(2) + html_content[article_match.end():]) file_was_changed = True + # Processing for the page builder API: + fn_match = re.search(r"(/|\\)reference\1taipy\.gui\.builder.(.*?)\1index.html", filename) + if fn_match is not None: + element_name = fn_match[2] + # Default value of properties appear as "dynamic(type" as "indexed(type" + prop_re = re.compile(r"\s*.*?" + + r"\s*\s*(.*?)\s*\s*", + re.S) + new_content = "" + last_location = 0 + for prop in prop_re.finditer(html_content): + if default_value_re := re.match("(dynamic|indexed)\((.*)", prop[1]): + new_content += html_content[last_location:prop.start(1)] + new_content += f"{default_value_re[2]}
{default_value_re[1]}" + last_location = prop.end(1) + if last_location: + file_was_changed = True + html_content = new_content + html_content[last_location:] + # 'default value' -> default value + dv_re = re.compile(r"&\#39;<i>(.*?)</i>&\#39;", re.S) + new_content = "" + last_location = 0 + for dv in dv_re.finditer(html_content): + new_content += html_content[last_location:dv.start()] + f"{dv[1]}" + last_location = dv.end() + if last_location: + file_was_changed = True + html_content = new_content + html_content[last_location:] # Handle title and header in packages documentation file FONT_SIZE_CHANGE='' def code(s: str) -> str: @@ -464,6 +494,7 @@ def code(s: str) -> str: sources = ", ".join(sorted(fixed_cross_refs[dest])) log.info(f"FIXED cross-ref to '{dest}' from {sources}") + # ################################################################################ # Functions that are used in the postprocessing phase. # I wish we could move them elsewhere, but couldn't figure out how @@ -489,6 +520,7 @@ def process_data_source_attr(html: str, env): else: return (False, None) + def process_links_to_github(html: str, env): _LINK_RE = re.compile(r"(?<=href=\"https://github.com/Avaiga/)(taipy-gui/tree/)\[BRANCH\](.*?\")") new_content = ""