Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Config Ref man #1851

Open
wants to merge 42 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
14efed4
Improve config doc and remove deprecated function.
jrobinAV Sep 25, 2024
5a3cd21
Update config.pyi
jrobinAV Sep 25, 2024
41ec8a6
Merge branch 'develop' into feature/#1130-config-ref-man
jrobinAV Sep 26, 2024
db75dcb
Apply suggestions from code review
jrobinAV Sep 26, 2024
cdeef18
Update config.pyi
jrobinAV Sep 26, 2024
91f730b
Merge branch 'develop' into feature/#1130-config-ref-man
jrobinAV Sep 27, 2024
912a70c
Improve config doc and remove deprecated function.
jrobinAV Sep 27, 2024
d776c0e
Merge branch 'develop' into feature/#1130-config-ref-man
jrobinAV Sep 30, 2024
33148cb
linter
jrobinAV Sep 30, 2024
84ec2c2
Config Reference manual
jrobinAV Oct 1, 2024
6d5f9c5
Update config.pyi
jrobinAV Oct 1, 2024
3b1e392
Ref man
jrobinAV Oct 1, 2024
04e20eb
Merge branch 'develop' into feature/#1130-config-ref-man
jrobinAV Oct 1, 2024
303567f
Ref man improvements
jrobinAV Oct 3, 2024
2eb19ff
yet some other improvements
jrobinAV Oct 3, 2024
5e19f8c
yet some other improvements
jrobinAV Oct 3, 2024
eba7f78
consistency
jrobinAV Oct 3, 2024
ff7f7c1
example
namnguyen20999 Oct 2, 2024
3e86861
linter
namnguyen20999 Oct 2, 2024
462446a
ruff
namnguyen20999 Oct 2, 2024
a246adb
per Fab
namnguyen20999 Oct 3, 2024
b71a4b4
per Fab
namnguyen20999 Oct 3, 2024
421c688
Stack broadcasts so that not one is lost (#1882)
FredLL-Avaiga Oct 2, 2024
7d17513
add on page load (#1883) (#1884)
dinhlongviolin1 Oct 3, 2024
f8a32c0
Toggle examples (#1885)
FredLL-Avaiga Oct 3, 2024
2428771
Feature/#923 create taipy common (#1833)
joaoandre-avaiga Oct 3, 2024
a521950
added inject by method
Sep 30, 2024
751a3ed
fixed issue of import in enterprise
Oct 2, 2024
d75e8a5
rename class
Oct 3, 2024
3bd7170
remove unnecessary inject_method fct
Oct 3, 2024
2171542
fixed wrong code
Oct 3, 2024
483ed86
manage broadcast (#1894)
FredLL-Avaiga Oct 3, 2024
f49b58e
Update README.md (#1869)
kushal34712 Oct 3, 2024
3a0f8c7
Update contributors.txt (#1877)
kushal34712 Oct 3, 2024
ba20fd9
Update CODE_OF_CONDUCT.md Corrected the Grammar Part (#1888)
DeepanshuProgrammer Oct 3, 2024
d544492
merge issues
jrobinAV Oct 3, 2024
cd0f701
merge develop
jrobinAV Oct 3, 2024
6e95b06
Update config.pyi
jrobinAV Oct 3, 2024
2db149f
Apply suggestions from code review
jrobinAV Oct 3, 2024
8b0f99f
make the refman works with taipy.common
jrobinAV Oct 3, 2024
f753425
Update config.pyi
jrobinAV Oct 3, 2024
62da7a8
Merge branch 'develop' into feature/#1130-config-ref-man
jrobinAV Oct 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions taipy/common/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.

"""# Taipy `config` Package

The `taipy.common.config` package provides features to configure a Taipy application.
""" The `taipy.common.config` package provides features to configure a Taipy application.
jrobinAV marked this conversation as resolved.
Show resolved Hide resolved

Its main class is the `Config^` singleton. It exposes various static methods
and attributes to configure the Taipy application and retrieve the configuration values.
Expand Down Expand Up @@ -50,8 +48,6 @@
from typing import List

from ._init import Config
from .checker.issue import Issue
from .checker.issue_collector import IssueCollector
from .common.frequency import Frequency
from .common.scope import Scope
from .global_app.global_app_config import GlobalAppConfig
Expand All @@ -60,20 +56,35 @@


def _config_doc(func):
def func_with_doc(section, attribute_name, default, configuration_methods, add_to_unconflicted_sections=False):
def func_with_doc(section, attr_name, default, configuration_methods, add_to_unconflicted_sections=False):
import os

if os.environ.get("GENERATING_TAIPY_DOC", None) and os.environ["GENERATING_TAIPY_DOC"] == "true":
with open("config_doc.txt", "a") as f:
with (open("config_doc.txt", "a") as f):
from inspect import signature

# Add the documentation for configure methods
for exposed_configuration_method, configuration_method in configuration_methods:
annotation = " @staticmethod\n"
sign = " def " + exposed_configuration_method + str(signature(configuration_method)) + ":\n"
doc = ' """' + configuration_method.__doc__ + '"""\n'
content = " pass\n\n"
f.write(annotation + sign + doc + content)
return func(section, attribute_name, default, configuration_methods, add_to_unconflicted_sections)

# Add the documentation for the attribute
clazz = section.__class__
annotation = ' @property\n'
sign = f" def {attr_name} (self) -> {section.__name__}:\n"
if issubclass(section, UniqueSection):
doc = f' """The configured {section.__name__} section."""\n'
elif issubclass(section, Section):
doc = f' """The configured {section.__name__} sections ."""\n'
else:
print(f" ERROR - Invalid section class: {section.__name__}")
return
content = " pass\n\n"
f.write(annotation + sign + doc + content)
return func(section, attr_name, default, configuration_methods, add_to_unconflicted_sections)

return func_with_doc

Expand Down
4 changes: 4 additions & 0 deletions taipy/common/config/checker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
""""""

from .issue import Issue
from .issue_collector import IssueCollector
13 changes: 6 additions & 7 deletions taipy/common/config/checker/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,21 @@ class Issue:
`Issue` is a dataclass that represents an issue detected during the configuration check
process. It contains the necessary information to understand the issue and help the user to fix
it.

Attributes:
level (str): Level of the issue among ERROR, WARNING, INFO.
field (str): Configuration field on which the issue has been detected.
value (Any): Value of the field on which the issue has been detected.
message (str): Human readable message to help the user fix the issue.
tag (Optional[str]): Optional tag to be used to filter issues.
"""

level: str
"""Level of the issue among ERROR, WARNING, INFO."""
field: str
"""Configuration field on which the issue has been detected."""
value: Any
"""Value of the field on which the issue has been detected."""
message: str
"""Human readable message to help the user fix the issue."""
tag: Optional[str]
"""Optional tag to be used to filter issues."""

def __str__(self) -> str:
"""Return a human-readable string representation of the issue."""
message = self.message

if self.value:
Expand Down
10 changes: 4 additions & 6 deletions taipy/common/config/checker/issue_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ class IssueCollector:
method. It contains all the collected issues separated by severity (ERROR, WARNING, INFO).
Each issue is an instance of the class `Issue^` and contains the necessary information to
understand the issue and help the user to fix it.

Attributes:
errors (List[Issue^]): List of ERROR issues collected.
warnings (List[Issue^]): List WARNING issues collected.
infos (List[Issue^]): List INFO issues collected.
all (List[Issue^]): List of all issues collected ordered by decreasing level (ERROR, WARNING and INFO).
"""

_ERROR_LEVEL = "ERROR"
Expand All @@ -41,18 +35,22 @@ def __init__(self) -> None:

@property
def all(self) -> List[Issue]:
"""List of all issues collected ordered by decreasing level (ERROR, WARNING and INFO)."""
return self._errors + self._warnings + self._infos

@property
def infos(self) -> List[Issue]:
"""List INFO issues collected."""
return self._infos

@property
def warnings(self) -> List[Issue]:
"""List WARNING issues collected."""
return self._warnings

@property
def errors(self) -> List[Issue]:
"""List of ERROR issues collected."""
return self._errors

def _add_error(self, field: str, value: Any, message: str, checker_name: str) -> None:
Expand Down
20 changes: 8 additions & 12 deletions taipy/common/config/common/frequency.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@
class Frequency(_ReprEnum):
"""Frequency of the recurrence of `Cycle^` and `Scenario^` objects.

This enumeration can have the following values:

- `DAILY`: Daily frequency, a new cycle is created for each day.
- `WEEKLY`: Weekly frequency, a new cycle is created for each week (from Monday to Sunday).
- `MONTHLY`: Monthly frequency, a new cycle is created for each month.
- `QUARTERLY`: Quarterly frequency, a new cycle is created for each quarter.
- `YEARLY`: Yearly frequency, a new cycle is created for each year.

The frequency must be provided in the `ScenarioConfig^`.

Each recurrent scenario is attached to the cycle corresponding to the creation date and the
Expand All @@ -24,18 +32,6 @@ class Frequency(_ReprEnum):
For instance, when scenarios have a _MONTHLY_ frequency, one cycle will be created for each
month (January, February, March, etc.). A new scenario created on February 10th, gets
attached to the _February_ cycle.

The frequency is implemented as an enumeration with the following possible values:

- With a _DAILY_ frequency, a new cycle is created for each day.

- With a _WEEKLY_ frequency, a new cycle is created for each week (from Monday to Sunday).

- With a _MONTHLY_ frequency, a new cycle is created for each month.

- With a _QUARTERLY_ frequency, a new cycle is created for each quarter.

- With a _YEARLY_ frequency, a new cycle is created for each year.
"""

DAILY = 1
Expand Down
6 changes: 3 additions & 3 deletions taipy/common/config/common/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ class Scope(_OrderedEnum):

This enumeration can have the following values:

- `GLOBAL`
- `CYCLE`
- `SCENARIO` (Default value)
- `GLOBAL`: Global scope, the data node is shared by all the scenarios.
- `CYCLE`: Cycle scope, the data node is shared by all the scenarios of the same cycle.
- `SCENARIO` (Default value): Scenario scope, the data node is unique to a scenario.

Each data node config has a scope. It is an attribute propagated to the `DataNode^`
when instantiated from a `DataNodeConfig^`. The scope is used to determine the
Expand Down
51 changes: 25 additions & 26 deletions taipy/common/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ def by_two(x: int):
??? example "Advanced use case"

The configuration can be done in three ways: Python code, configuration files, or
environment variables. All configuration manners are ultimately merged (overriding the previous way
environment variables. All configuration manners are ultimately merged (overriding the previous
way) to create a final applied configuration. Please refer to the
[advanced configuration](../../userman/advanced_features/configuration/advanced-config.md)
[advanced configuration](../../../../../userman/advanced_features/configuration/advanced-config.md)
section from the user manual for more details.

2. Attributes and methods to retrieve the configuration values.
Expand Down Expand Up @@ -103,12 +103,6 @@ def by_two(x: int):
file and replace the current Python configuration.
- *Override the configuration*: Use the `Config.override()^` method to load a TOML
configuration file and override the current Python configuration.

Attributes:
global_config (GlobalAppConfig): configuration values related to the global
application as a `GlobalAppConfig^`.
unique_sections (Dict[str, UniqueSection]): A dictionary containing all unique sections.
sections (Dict[str, Dict[str, Section]]): A dictionary containing all non-unique sections.
"""

_ENVIRONMENT_VARIABLE_NAME_WITH_CONFIG_PATH = "TAIPY_CONFIG_PATH"
Expand All @@ -125,19 +119,22 @@ def by_two(x: int):

@_Classproperty
def unique_sections(cls) -> Dict[str, UniqueSection]:
"""A dictionary containing all unique sections."""
return cls._applied_config._unique_sections

@_Classproperty
def sections(cls) -> Dict[str, Dict[str, Section]]:
"""A dictionary containing all non-unique sections."""
return cls._applied_config._sections

@_Classproperty
def global_config(cls) -> GlobalAppConfig:
"""configuration values related to the global application as a `GlobalAppConfig^`."""
return cls._applied_config._global_config

@classmethod
@_ConfigBlocker._check()
def load(cls, filename):
def load(cls, filename: str) -> None:
"""Load a configuration file.

The current Python configuration is replaced and the Config compilation is triggered.
Expand All @@ -151,22 +148,22 @@ def load(cls, filename):
cls.__logger.info(f"Configuration '{filename}' successfully loaded.")

@classmethod
def export(cls, filename):
def export(cls, filename: str) -> None:
"""Export a configuration.

The export is done in a toml file.
The export is done in a toml file. The exported configuration is taken
from the Python code configuration.

The exported configuration is taken from the Python code configuration.
Note:
If *filename* already exists, it is overwritten.

Parameters:
filename (Union[str, Path]): The path of the file to export.
Note:
If *filename* already exists, it is overwritten.
"""
cls._serializer._write(cls._python_config, filename)

@classmethod
def backup(cls, filename):
def backup(cls, filename: str) -> None:
"""Backup a configuration.

The backup is done in a toml file.
Expand All @@ -175,16 +172,17 @@ def backup(cls, filename):
the application: the Python code configuration, the file configuration and the environment
configuration.

Parameters:
filename (Union[str, Path]): The path of the file to export.
Note:
If *filename* already exists, it is overwritten.

Parameters:
filename (Union[str, Path]): The path of the file to export.
"""
cls._serializer._write(cls._applied_config, filename)

@classmethod
@_ConfigBlocker._check()
def restore(cls, filename):
def restore(cls, filename: str) -> None:
"""Restore a configuration file and replace the current applied configuration.

Parameters:
Expand All @@ -196,7 +194,7 @@ def restore(cls, filename):

@classmethod
@_ConfigBlocker._check()
def override(cls, filename):
def override(cls, filename: str) -> None:
"""Load a configuration from a file and overrides the current config.

Parameters:
Expand All @@ -209,12 +207,12 @@ def override(cls, filename):
cls.__logger.info(f"Configuration '{filename}' successfully loaded.")

@classmethod
def block_update(cls):
def block_update(cls) -> None:
"""Block update on the configuration signgleton."""
_ConfigBlocker._block()

@classmethod
def unblock_update(cls):
def unblock_update(cls) -> None:
"""Unblock update on the configuration signgleton."""
_ConfigBlocker._unblock()

Expand All @@ -225,6 +223,7 @@ def configure_global_app(cls, **properties) -> GlobalAppConfig:

Parameters:
**properties (Dict[str, Any]): A dictionary of additional properties.

Returns:
The global application configuration.
"""
Expand Down Expand Up @@ -255,7 +254,7 @@ def check(cls) -> IssueCollector:

@classmethod
@_ConfigBlocker._check()
def _register_default(cls, default_section: Section):
def _register_default(cls, default_section: Section) -> None:
if isinstance(default_section, UniqueSection):
if cls._default_config._unique_sections.get(default_section.name, None):
cls._default_config._unique_sections[default_section.name]._update(default_section._to_dict())
Expand All @@ -271,7 +270,7 @@ def _register_default(cls, default_section: Section):

@classmethod
@_ConfigBlocker._check()
def _register(cls, section):
def _register(cls, section) -> None:
if isinstance(section, UniqueSection):
if cls._python_config._unique_sections.get(section.name, None):
cls._python_config._unique_sections[section.name]._update(section._to_dict())
Expand All @@ -289,7 +288,7 @@ def _register(cls, section):
cls._compile_configs()

@classmethod
def _override_env_file(cls):
def _override_env_file(cls) -> None:
if cfg_filename := os.environ.get(cls._ENVIRONMENT_VARIABLE_NAME_WITH_CONFIG_PATH):
if not os.path.exists(cfg_filename):
cls.__logger.error(
Expand All @@ -303,7 +302,7 @@ def _override_env_file(cls):
cls.__logger.info(f"Configuration '{cfg_filename}' successfully loaded.")

@classmethod
def _compile_configs(cls):
def _compile_configs(cls) -> None:
Config._override_env_file()
cls._applied_config._clean()
if cls._default_config:
Expand All @@ -316,7 +315,7 @@ def _compile_configs(cls):
cls._applied_config._update(cls._env_file_config)

@classmethod
def __log_message(cls, config):
def __log_message(cls, config) -> None:
for issue in config._collector._warnings:
cls.__logger.warning(str(issue))
for issue in config._collector._infos:
Expand Down
Loading