From 2cf149cde77e8d2d6d4b54cc0a762cafc9d15536 Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Wed, 9 Feb 2022 17:36:53 -0500 Subject: [PATCH 1/7] Add link to Microsoft Error Messages guidelines and incorporate information on building a PDF of the documentation locally on Windows --- doc/source/guidelines/dev_practices.rst | 6 + doc/source/guidelines/doc_practices.rst | 255 +++++++++++++++--------- 2 files changed, 162 insertions(+), 99 deletions(-) diff --git a/doc/source/guidelines/dev_practices.rst b/doc/source/guidelines/dev_practices.rst index 858f1b506..dc567fff0 100644 --- a/doc/source/guidelines/dev_practices.rst +++ b/doc/source/guidelines/dev_practices.rst @@ -106,6 +106,12 @@ any new issues from your changes. pytest -v --cov _unittest +Error Messages +~~~~~~~~~~~~~~ +When writing error messages, follow the `Error Message Guidelines +`_ +on the Microsoft website to ensure that your messages are well crafted. + Spelling and Code Style ~~~~~~~~~~~~~~~~~~~~~~~ If you are using Linux or Mac OS, run spelling and coding style checks: diff --git a/doc/source/guidelines/doc_practices.rst b/doc/source/guidelines/doc_practices.rst index 1648cd030..de8f64f10 100644 --- a/doc/source/guidelines/doc_practices.rst +++ b/doc/source/guidelines/doc_practices.rst @@ -16,13 +16,18 @@ key. To keep documentation up to date with rapdily evolving code: - Support contributions from both inside and outside of the development team - Perform periodic reviews +Understanding Documentation Sources +------------------------------------ The generation of PyAnsys documentation uses `Sphinx `__ and an Ansys-branded theme (`pyansys-sphinx-theme `_) -to assemble content that comes from docstrings, reStructuredText (RST) files, and Python (PY) -example files. +to assemble content in: + +- Docstrings +- reStructuredText (RST) files +- Python (PY) example files Docstrings ----------- +~~~~~~~~~~ Docstrings must be formatted so that Sphinx can parse them. You can use either of these Sphinx extensions: @@ -46,9 +51,9 @@ recommend the use of numpy-style docstrings so that there is consistency across PyAnsys libraries. For more information, see :ref:`api_documentation`. RST Files ---------- +~~~~~~~~~ To provide general usage information in your documentation, use your favorite editor to -create RST files that you then place in the repository's ``doc/`` directory. The ``index.rst`` +create RST files that you then place in the repository's ``doc\`` directory. The ``index.rst`` file in the ``doc\source`` directory defines the first level of your documentation hierarchy. The ``toctree`` directive indicates the maximum number of heading levels that the documentation is to display. Below this directive are the directory names for your documentation sections. @@ -80,7 +85,7 @@ guide. Within RST files, heading titles are followed by a line having a string of characters that is the same length as the heading title. If the length of the characters -under the heading title do not match the length of the heading title, Sphinx will generate a warning. +under the heading title do not match the length of the heading title, Sphinx generates a warning. For consistency within PyAnsys libraries, the use of these special characters is recommended for headings but are not enforced: @@ -97,7 +102,7 @@ its HTML pages and then explore the RST files in its repository. This will help the syntax and see how RST files have been nested to create this guide. Examples --------- +~~~~~~~~ Examples come in two formats: - Basic code snippets demonstrating some functionality @@ -109,9 +114,7 @@ repository. All of these examples, which should be PEP 8-compliant, are compiled during the build process. Always ensure that your examples run properly locally because they will be verified through the CI performed via GitHub Actions. -Adding a New Example -~~~~~~~~~~~~~~~~~~~~ -Adding a standalone example consists of placing it in an applicable subfolder in the ``examples`` +Adding a new standalone example consists of placing it in an applicable subfolder in the ``examples`` directory. If none of the existing directories match the category of your example, create a new subfolder with a ``README.txt`` file describing the new category. Because these examples are built using the `Sphinx-Gallery `_ @@ -124,7 +127,9 @@ Accessing a Library's Documentation Documentation for the latest stable release of a PyAnsys library is accessible from its repository. You can generally access the latest development version of the documentation tracking the ``main`` branch by adding the prefix ``dev.`` to -the URL for the latest stable release. For example, consider PyAEDT documentation. +the URL for the latest stable release. + +For example, consider PyAEDT documentation: - The URL for documentation of the latest stable release is ``_. - The URL for documentation of the lastest development version is ``_. @@ -132,92 +137,27 @@ the URL for the latest stable release. For example, consider PyAEDT documentatio The latest development versions of both the library and its documentation are automatically kept up-to-date via GitHub actions. -.. _doc_building: - -Building Documentation Locally ------------------------------- -You can build and verify the HTML documentation for a PyAnsys library locally -by installing Sphinx and other documentation build dependencies. - -Setting Up Your Machine -~~~~~~~~~~~~~~~~~~~~~~~ -Anaconda provides Python and tools, such as a Python IDE (Interactive Development Environment), -a Python command line editor, and Sphinx dependencies. This gives you what you need to get up -and running. - -#. Install the `Anaconda individual edition `_. - -#. If a PyAnsys library already exists, create a directory in which to place a clone of its GitHub repository. - -#. Clone the PyAnsys library's GitHub repository. For more information, see :ref:`cloning`. - -#. If you have not yet cloned the ``pyansys-sphinx-theme`` repository, clone it. - -Installing Build Requirements -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can build documentation for the ``dev_guide`` and ``pyansys-sphinx-theme`` repositories without -installing a PyAnsys library in development mode. However, when you push changes that you have made -in a local branch to the GitHub repository for other PyAnsys libraries, CI checks typically require -that the full library is installed. - -#. In Anaconda Powershell, navigate to the base directory in the library's cloned repository. - -#. If your library must be installed in development mode, enter: - - .. code:: - - pip install -e . - -#. To install the build requirements for generating documentation, enter: - - .. code:: - - pip install -r requirements_docs.txt - -#. If you are running on a Linux/Mac OS, to build the documentation, enter: - - .. code:: - - make -C doc html - -#. If you are running on Windows, to build the documentation, enter two - commands: - - .. code:: - - cd doc - make.bat html - - - As Sphinx is generating HTML output in the library's ``doc\_build\html`` folder, - Anaconda Powershell displays any errors and warnings for unexpected indentations, - bad target locations for links, missing files, and extra files included in the - repository but not referenced by any ``index.rst`` file. - -#. Resolve all indicated issues before submitting a pull request (PR) to push - your changes to the library's GitHub repository. - -#. After local documentation builds successfully, navigate to ``doc/_build/html/`` - and use your browser to open the ``index.html`` file to review the documentation, - repeating the local build process until there are no errors or obvious issues. +To make documentation changes, you create a branch with a name that begins with a prefix of +``doc/`` that is then followed by a short description of what you are changing. For more +information, see :ref:`branch_naming`. -.. note:: - You can use ``make.bat`` to build more than HTML output. To view a summary of - all target options, enter ``make.bat``. - -Your next step is to push your changes to the library's GitHub repository -by creating a PR. For more information, see :ref:`create_pr`. +As you are making changes in this branch, you want to periodically generate the documentation +locally so that you can test your changes before you create a GitHub pull request. For more +information, see :ref:`doc_building`. It is also possible for you to build a PDF +of your documentation locally on Windows as described in :ref:`pdf_building`. .. _cloning: Cloning a GitHub Repository --------------------------- -While developers likely know how to clone a GitHub repository, technical documentation -specialists may not know how to do this. You can easily use either Windows PowerShell -or GitBash. +Contributing to a GitHub repository requires that you first clone the repository. While developers +likely know many ways to do this, technical documentation specialists may need to review the +following instructions for using either Windows PowerShell or GitBash to clone a GitHub repository. Using Windows PowerShell to Clone a GitHub Repository ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To use Windows PowerShell to clone a GitHub repository: + #. In Windows PowerShell, navigate to the directory on your machine where you want to clone GitHub repositories. @@ -247,13 +187,15 @@ Using Windows PowerShell to Clone a GitHub Repository Using GitBash to Clone a GitHub Repository ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To use GitBase to clone a GitHub repository: + #. In the directory where you want to clone PyAnsys repositories, right-click and select ``GitBash Here``. #. Type ``git clone`` followed by the address of the repo to clone. -For example, to clone the ``pyansys-sphinx-theme`` repository, you would -type and enter: + +For example, you clone the ``pyansys-sphinx-theme`` repository with: .. code:: @@ -263,13 +205,11 @@ type and enter: Pushing Changes to the GitHub Repository ---------------------------------------- -Once you have tested your changes in local documentation builds and are -satisifed with them, you can push them to the library's GitHub repository. -You can use Git commands or Git Extension to accomplish this. - -For documentation changes, the branch name should always have a prefix of ``doc/`` -followed by a short description of what you've changed. For more information, see -:ref:`branch_naming`. +As you make changes in your ``doc/`` branch, you want to periodically test then in +local documentation builds as described in :ref:`doc_building`. After you resolve +any issues and are satisfied with what apears in a local build, you are ready +to push your changes to the library's GitHub repository. To accomplish this, +you can use either Git commands or Git Extensions. Using Git Commands to Push Changes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -317,8 +257,7 @@ To use Git commands to push your changes to the GitHub repository: followed by the branch name. For the given example, you would enter: - - + .. code:: git push --set-upstream origin doc/edit_contributing @@ -356,6 +295,7 @@ To use Git Extensions to push your changes to the GitHub repository: #. Create the PR as described in :ref:`create_pr`. + .. _create_pr: Creating the GitHub PR @@ -378,3 +318,120 @@ the GitHub PR: If you need to change a PR title, to its right, click the ``Edit`` button, which becomes a ``Save`` button while you are in editing mode. + +.. _doc_building: + +Building Documentation Locally +------------------------------ +You can build and verify the HTML documentation for a PyAnsys library locally +by installing Sphinx and other documentation build dependencies. + +Setting Up Your Machine +~~~~~~~~~~~~~~~~~~~~~~~ +Anaconda provides Python and tools, such as a Python IDE (Interactive Development Environment), +a Python command line editor, and Sphinx dependencies. This gives you what you need to get up +and running. + +#. Install the `Anaconda individual edition `_. + +#. If a PyAnsys library already exists, create a directory in which to place a clone of its GitHub repository. + +#. Clone the PyAnsys library's GitHub repository. For more information, see :ref:`cloning`. + +#. If you have not yet cloned the ``pyansys-sphinx-theme`` repository, clone it. + +Installing Build Requirements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You can build documentation for the ``dev_guide`` and ``pyansys-sphinx-theme`` repositories without +installing a PyAnsys library in development mode. However, when you push changes that you have made +in a local branch to the GitHub repository for other PyAnsys libraries, CI checks typically require +that the full library is installed. + +#. In Anaconda Powershell, navigate to the base directory in the library's cloned repository. + +#. If your library must be installed in development mode, enter: + + .. code:: + + pip install -e . + +#. To install the build requirements for generating documentation, enter: + + .. code:: + + pip install -r requirements_docs.txt + +#. If you are running on a Linux/Mac OS, to build the documentation, enter: + + .. code:: + + make -C doc html + +#. If you are running on Windows, to build the documentation, enter two + commands: + + .. code:: + + cd doc + .\make.bat html + + + As Sphinx is generating HTML output in the library's ``..\doc\_build\html`` folder, + Anaconda Powershell displays any errors and warnings for unexpected indentations, + bad target locations for links, missing files, and extra files included in the + repository but not referenced by any ``index.rst`` file. + +#. Resolve all indicated issues before submitting a pull request (PR) to push + your changes to the library's GitHub repository. + +#. After local documentation builds successfully, navigate to ``doc/_build/html/`` + and use your browser to open the ``index.html`` file to review the documentation, + repeating the local build process until there are no errors or obvious issues. + +.. note:: + You can use ``make.bat`` to build more than HTML output. To view a summary of + all target options, enter ``make.bat``. + +Your next step is to push your changes to the library's GitHub repository +by creating a PR. For more information, see :ref:`create_pr`. + +.. _pdf_building: + +Building a PDF of Your Documentation Locally +-------------------------------------------- +Some libraries supply a link to a PDF of the documentation under 'Assets' in the +release notes for a version. On Linux, building this PDF can be set up as an +automated process. On Windows, building a PDF is a manual process that you run +locally: + +#. Install `MiKTeX `_ for Windows, selecting the + recommended option for installing it for only your own use. +#. From the Windows Start menu, start the MiKTeX Console. +#. On the Welcome page, click ``Check for updates`` and install any available + updates. +#. Install the latest version of Strawbery Perl, which enables you to build + LaTeX files, accepting the default installation location (``C:\Strawberry\``). +#. In the Command Prompt window, type ``perl-v`` to test that you installation is + successful. +#. Ensure that these Perl directory locations have been added to your ``Path`` + system environment variable: + + - C:/Strawberry/c/bin + - C:/Strawberry/perl/site/bin + - C:/Strawberry/perl/bin + + +#. In Anaconda PowerShell, navigate to the ``doc`` directory with: + + .. code:: + + cd C:\AnsysDev\GitRepos\PyAnsys\dev-guide\doc + + +#. Generate LaTeX files and a PDF from these files in ``..\doc\build\latex`` + with: + + .. code:: + + .\make latexpdf + From 6f66f2c1624b1f06ccb373032f54d104e8277c5b Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Thu, 10 Feb 2022 12:06:24 -0500 Subject: [PATCH 2/7] Incorporate Pythonic message sources and edit logging content --- doc/source/guidelines/dev_practices.rst | 11 +- doc/source/guidelines/logging.rst | 350 ++++++++++++------------ 2 files changed, 178 insertions(+), 183 deletions(-) diff --git a/doc/source/guidelines/dev_practices.rst b/doc/source/guidelines/dev_practices.rst index dc567fff0..83e9d903d 100644 --- a/doc/source/guidelines/dev_practices.rst +++ b/doc/source/guidelines/dev_practices.rst @@ -108,9 +108,14 @@ any new issues from your changes. Error Messages ~~~~~~~~~~~~~~ -When writing error messages, follow the `Error Message Guidelines -`_ -on the Microsoft website to ensure that your messages are well crafted. +For general information on writting good error messages, see Microsoft's +`Error Message Guidelines `_. + +For information specific to writing Pythonic error messages, see: + +- `Python Exception Handling `_ +- `7 Tips to Improve Your Error Handling in Python `_ +- `Python Exception TUtorial: Printing Error Messges `_ Spelling and Code Style ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/guidelines/logging.rst b/doc/source/guidelines/logging.rst index 37e2809f8..a357d7de4 100644 --- a/doc/source/guidelines/logging.rst +++ b/doc/source/guidelines/logging.rst @@ -1,65 +1,63 @@ +.. _logging: + Logging Guidelines ################## -This section describes several guidelines for logging in PyAnsys libraries. +This section provides guidelines for logging in PyAnsys libraries. These guidelines are best practices discovered through implementing logging -services and modules within PyAnsys libraries. Suggestions and improvements are -welcome. -External resources also describe `basic +services and modules within PyAnsys libraries. We welcome suggestions and +improvements. + +Also see external resources for `basic `__ and `advanced `__ technics. -Description and usage +Description and Usage ===================== -Logging helps to track events occurring in the application. For each of them a -log record is created. It contains a detailed set of information about the -current application operation. Whenever an information must be exposed, -displayed and shared, logging is the way to do it. -It is destinated to both the users and the application developers. It can serve -several purposes: - - - extract some valuable data for the final users to know the status of their work. - - track the progress and the course of the application usage. - - provide the developer with as much information as possible if an issue happens. - +Logging helps to track events occurring in the application. A log record is +created for each event. This record contains detailed information about the +current application operation. Whenever information must be exposed, displayed, +and shared, logging is the way to do it. + +Logging is beneficial to both users and application developers. It serves several +purposes: + + - Extracts some valuable data for the final users to know the status of their work + - Tracks the progress and the course of the application usage + - Provides the developer with as much information as possible if an issue happens + The message logged can contain generic information or embed data specific to the -current session. -Message content is associated to a level of severity (info, warning, error...). -Generally, this degree of significance indicates the recipient of the message. -An info message is directed to the user while a debug message is useful for the -developer itself. - - -Logging in PyAnsys Libraries -============================ - -The logging capabilities in PyAnsys libraries should be built upon the `standard -logging `__ library. PyAnsys -libries should not to replace this library, rather provide a standardized way to -interact between the built-in :mod:`logging` library and ``PyAnsys`` libraries. - +current session. Message content is associated to a severity level, such as info, +warning, and error. Generally, the severity level indicates the recipient of the message. +For example, an info message is directed to the user, while a debug message is directed +to the developer. Logging Best Practices ----------------------- - -Avoid printing to the console -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A common habit while prototyping a new feature is to print message into the -command line executable. Instead of using the common ``Print()`` method, it is -advised to use a ``StreamHandler`` and redirect its content. Indeed that will -allow to filter messages based on their level and apply properly the formatter. -To do so, a boolean argument can be added in the initializer of the ``Logger`` -class. This argument specifies how to handle the stream. - -Enable/Disable handlers +====================== +The logging capabilities in PyAnsys libraries should be built upon the `standard +logging `__ library. A PyAnsys +library should not replace the standard logging library but rather provide a +standardized way for the built-in :mod:`logging` library and the PyAnsys library +to interact. Subsequent sections provide some best practices. + +Avoid Printing to the Console +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A common habit while prototyping a new feature is to print a message into the +command line executable. Instead of using the common ``Print()`` method, we +recommend using a ``StreamHandler`` and redirecting its content. This will +allow messages to be filtered based on their severity level and apply formatting +properly. To accomplish this, add a Boolean argument in the initializer +of the ``Logger`` class that specifies how to handle the stream. + +Enable/disable Handlers ~~~~~~~~~~~~~~~~~~~~~~~ -Sometimes the user might want to disable specific handlers such as a file -handler where log messages are written. If so, the existing handler must be -properly closed and removed. Otherwise the file access might be denied later -when you try to write new log content. +You might sometimes want to disable a specific handler, such as a file +handler where log messages are written. If so, you must property close +and remove the existing handler. Otherwise, you might be denied file access +later when you try to write new log content. -Here's one approach to closing log handlers. +Here is an example of how to close a log handler: .. code:: python @@ -69,15 +67,16 @@ Here's one approach to closing log handlers. design_logger.removeHandler(handler) -App Filter -~~~~~~~~~~ -A filter shows all its value when the content of a message depends on some +Use App Filters +~~~~~~~~~~~~~~~ +An app filter shows all its value when the content of a message depends on some conditions. It injects contextual information in the core of the message. -This can be useful to harmonize the message rendering when the application -output is not consistent and vary upon the data processed. -It requires the creation of class based on the logging.Filter and the -implementation of the ``filter`` method. This method will contain all the -modified content send to the stream. +This can be used to harmonize message rendering when the application +output varies based on the data processed. + +Using an app filter requires the creation of a class based on the ``logging.Filter`` +and the implementation of the ``filter`` method. This method will contain all +modified content to send to the stream: .. code:: python @@ -113,32 +112,35 @@ modified content send to the stream. self.global_logger.addHandler(self._std_out_handler) -String format -~~~~~~~~~~~~~ -Even if the current practice recommends using the f-string to format most -strings, when it comes to logging, the former %-formatting is preferable. This -way the string format is not evaluated at runtime. It is deferred and evaluated -only when the message is emitted. If there is any formatting or evaluation -error, these will be reported as logging errors and will not halt code -execution. +Use %-Formatting for Strings +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Although using the f-string for formatting most strings is often recommended, +when it comes to logging, using the former %-formatting is preferable. +When %-formatting is used, the string is not evaluated at runtime. Instead, it +is evaluated only when the message is emitted. If any formatting or evaluation +errors occur, they will be reported as logging errors and will not halt code. .. code:: python logger.info("Project %s has been opened.", project.GetName()) -Application or Service Logging -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The following guidelines describe "Application" or "Service" logging module for -a PyAnsys library, where a PyAnsys library is used to extend or expose features -from an Ansys application, product, or service that may be local or remote. +'Application' and 'Service' Logging Modules +=========================================== +PyAnsys libraries use 'Application' and 'Service' logging modules to extend +or expose features from an Ansys application, product, or service, which may +be local or remote. -This section describes two main loggers for a PyAnsys library that exposes or -extends a service based application, the *Global logger* and the *Instance -logger*. These loggers are customized classes that wrap :class:`logging.Logger` -from :mod:`logging` module and add specific features to it. -:ref:`logging_in_pymapdl_figure` outlines the logging approach used by PyMAPDL -and the scopes of the global and local loggers. +There are two main loggers for a PyAnsys library that expose or +extend a service-based application: + +- Global logger +- Instance logger + +These loggers are customized classes that wrap the :class:`logging.Logger` +class from the :mod:`logging` module and add specific features to it. This +image shows the logging approach used by PyMAPDL and the scopes +of the global and instance loggers. .. _logging_in_pymapdl_figure: @@ -147,48 +149,50 @@ and the scopes of the global and local loggers. :alt: Logging in PyMAPDL :figclass: align-center - **Figure 1: Example Logging Structure in PyMAPDL** -The source for this example logger can be found both within developers -guide repository at `pyansys_logging.py -`_ -as well as below in the collapsable section below: +You can find the source for this example logger in the collapsable section below +and in the ``dev_guide`` repository at `pyansys_logging.py +`_. -.. collapse:: Example PyAnsys custom logger module +.. collapse:: Example PyAnsys Custom Logger Module .. literalinclude:: ../../../logging/pyansys_logging.py -Following are some unit tests demonstatring how to use the code implemented above: -.. collapse:: How to use PyAnsys custom logger module +Some unit tests demonstrating how to use the PyAnsys custom logger module implemented +in the above code are shown in this collapsible section: + +.. collapse:: How to Use the PyAnsys Custom Logger Module .. literalinclude:: ../../../logging/test_pyansys_logging.py -Example Global logger -~~~~~~~~~~~~~~~~~~~~~ -There is a global logger named ``py*_global`` which is created when importing -``ansys.product.service`` (``ansys.product.service.__init__``). This logger is -recommended for most scenarios, especially when complex modules or classes are -not involved, since it does not track instances, rather can be used globally. -If you intend to log the initialization of a library or module, you should use -this logger. To use this global logger, you must import it at the top of your -script or module: +Global Logger +============= + +A global logger named ``py*_global`` is created when importing +``ansys.product.service`` (``ansys.product.service.__init__``). This logger +does not track instances but rather is used globally. Consequently, using +it is recommended for most scenarios, especially those where simple modules +or classes are involved. + +For example, if you intend to log the initialization of a library or module, +import the global logger at the top of your script or module: .. code:: python from ansys.product.service import LOG -You could also rename it to avoid conflicts with other loggers (if any): +If the default name of the global logger is in conflict with the name of +another logger, you can rename it with: .. code:: python from ansys.product.service import LOG as logger -It should be noted that the default logging level of ``LOG`` is -``ERROR`` (``logging.ERROR``). To change this and output different -ferror level messages you can use the next approach: +The default logging level of the global logger is ``ERROR`` (``logging.ERROR``). +You can change the output to a different error level with: .. code:: python @@ -197,17 +201,17 @@ ferror level messages you can use the next approach: LOG.stdout_handler.setLevel('DEBUG') # if present -Alternatively, you can use: +Alternatively, you can use this approach to ensure that all +handlers are set to the desired log level: .. code:: python LOG.setLevel('DEBUG') -This way ensures all the handlers are set to the desired log level. - -By default, this logger does not log to a file. If you wish to do so, -you can add a file handler using: +By default, the global logger does not log to a file. However, you can +enable logging to both a file and the standard output by adding +a file handler: .. code:: python @@ -215,12 +219,11 @@ you can add a file handler using: file_path = os.path.join(os.getcwd(), 'pylibrary.log') LOG.log_to_file(file_path) -This enables logging to that file in addition of the standard output. If you -wish to change the characteristics of this global logger from the beginning of +If you want to change the characteristics of the global logger from the beginning of the execution, you must edit the file ``__init__`` in the directory of your library. -To log using this logger, simply call the desired method as a normal logger. +To log using the global logger, simply call the desired method as a normal logger: .. code:: python @@ -233,30 +236,29 @@ To log using this logger, simply call the desired method as a normal logger. | DEBUG | | __init__ | | This is LOG debug message. -Instance logger -~~~~~~~~~~~~~~~ -Every time that the class ``_MapdlCore`` is instantiated, a logger is created. -This logger is recommended when using the ``pool`` library or when using -multiple instances of ``Mapdl``. The main feature of this logger is that it -tracks each instance and it includes its name when logging. The name of the -instances are unique. For example in case of using the ``gRPC`` ``Mapdl`` -version, its name includes the IP and port of the correspondent instance, making -unique its logger. - +Instance Logger +=============== +An instance logger is created every time that the class ``_MapdlCore`` is +instantiated. Using this instance logger is recommended when using the ``pool`` +library or when using multiple instances of ``Mapdl``. The main feature of the instance +logger is that it tracks each instance and includes the instance name when logging. +The names of instances are unique. For example, when using the ``gRPC`` ``Mapdl`` +version, the instance name includes the IP and port of the corresponding instance, +making the logger unique. -The instance loggers can be accessed in two places: +You can access instance loggers in two places: -* ``_MapdlCore._log``. For backward compatibility. -* ``LOG._instances``. This field is a ``dict`` where the key is the - name of the created logger. +* ``_MapdlCore._log`` for backward compatibility +* ``LOG._instances``, which is a field of the ``dict`` data type with a key that + is the name of the created logger. These instance loggers inherit from the ``pymapdl_global`` output handlers and -logging level unless otherwise specified. The way this logger works is very -similar to the global logger. You can add a file handler if you wish using the -method ``log_to_file`` or change the log level using +logging level unless otherwise specified. An instance logger works similarly to +the global logger. If you want to add a file handler, use the method +``log_to_file``. If you want to change the log level, use the method :meth:`logging.Logger.setLevel`. -You can use this logger like this: +Here is an example of how to use an instance logger: .. code:: python @@ -270,57 +272,49 @@ You can use this logger like this: -Wrapping Other Loggers -~~~~~~~~~~~~~~~~~~~~~~ -A product, due to its architecture can be made of several loggers. The -``logging`` library features allows to work with a finite number of loggers. The -factory function logging.getLogger() helps to access each logger by its name. In -addition of this naming-mappings, a hierachy can be established to structure the -loggers parenting and their connection. - - -For instance, if an ANSYS product is using a pre-exsiting custom logger -encapsulated inside the product itself, the will benefit from -exposing it through the standard python tools. It is recommended to use the +Ansys Product Loggers +===================== +An Ansys product, due to its architecture, can have several loggers. The +``logging`` library features support working with a finite number of loggers. The +factory function ``logging.getLogger()`` helps to access each logger by its name. In +addition to name mappings, a hierachy can be established to structure the +loggers' parenting and their connections. + +For example, if an Ansys product is using a pre-exsiting custom logger +encapsulated inside the product itself, the ** will benefit from +exposing it through the standard Python tools. We recommend that you use the standard library as much as possible. It will facilitate every contribution --both external and internal- to the by exposing common tools that -are widely spread. Each developer will be able to operate quickly and -autonomously. -The project will take advantage of the entire set of features exposed in the -standard logger and all the upcoming improvements. - -Create a custom log handler to catch each product message and redirect them on another logger: -============================================================================================== - -Context: --------- - -AEDT product has its own internal logger called the message manager made of 3 main destinations: - - * *Global*: for the entire Project manager - * *Project*: related to the project - * *Design*: related to the design (most specific destination of each 3 loggers.) - -The message manager is not using the standard python logging module and this -might be a problem later when exporting messages and data from each ANSYS -product to a common tool. In most of the cases, it is easier to work with the -standard python module to extract data. -In order to overcome this limitation, the existing message manager is wrapped -into a logger based on the standard python :mod:`logging` module. - +to the **, both external and internal, by exposing common tools that +are widely adopted. Each developer will be able to operate quickly and +autonomously. The project will take advantage of the entire set of features exposed +in the standard logger and all the upcoming improvements. + +Custom Log Handlers +=================== +You might need to catch Ansys product messages and redirect them to another +logger. For example, Ansys Electronics Desktop (AEDT) has its own internal +logger called the *message manager*, which has three main destinations: + + - *Global*, which is for the entire project manager + - *Project*, which is related to the project + - *Design*, which is related to the design, making it the most specific + destination of the three loggers + +The message manager does not use the standard Python logging module, which +can be a problem when exporting messages and data from it to a common tool. +In most cases, it is easier to work with the standard Python module to extract +data. To overcome this AEDT limitation, you must wrap the existing message +manager into a logger based on the standard Python :mod:`logging` module: .. figure:: images/log_flow.png :align: center :alt: Loggers message passing flow. :figclass: align-center - **Figure 1: Loggers message passing flow.** - - -This wrapper implementation boils down to a custom handler. It is based on a -class inherited from logging.Handler. The initializer of this class will require -the message manager to be passed as an argument in order to link the standard -logging service with the ANSYS internal message manager. +The wrapper implementation is essentially a custom handler based on a +class inherited from ``logging.Handler``. The initializer of this class +requires the message manager to be passed as an argument to link the standard +logging service with the AEDT message manager. .. code:: python @@ -337,18 +331,14 @@ logging service with the ANSYS internal message manager. pass -The purpose of this class is to send log messages in AEDT logging stream. +The purpose of this class is to send log messages in the AEDT logging stream. One of the mandatory actions is to overwrite the ``emit`` function. This method -operates as a proxy. It will dispatch all the log message toward the message -manager. -Based on the record level, the message is sent to the appropriate log level -(debug, info, error...) into the message manager to fit the level provided by -the ANSYS product. -As a reminder the record is an object containing all kind of information related -to the event logged. - -This custom handler is used into the new logger instance (the one based on the -standard library). -A good practice before to add a handler on any logger is to verify if any -appropriate handler is already available in order to avoid any conflict, message -duplication... +operates as a proxy, dispatching all log messages to the message manager. +Based on the record level, the message is sent to the appropriate log level, such +as debug, info, or error, into the message manager to fit the level provided by +the Ansys product. As a reminder, the record is an object containing all kind of +information related to the event logged. + +This custom handler is use in the new logger instance (the one based on the +standard library). To avoid any conflict or message duplication, before adding +a handler on any logger, verify if an appropriate handler is already available. From 6cccc5eb5ff1cb0e8b2faa1c302ad6b0bb4ee9ee Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Thu, 10 Feb 2022 12:16:17 -0500 Subject: [PATCH 3/7] Incorporate review comments --- doc/source/guidelines/dev_practices.rst | 3 ++- doc/source/guidelines/doc_practices.rst | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/source/guidelines/dev_practices.rst b/doc/source/guidelines/dev_practices.rst index 83e9d903d..550b6f802 100644 --- a/doc/source/guidelines/dev_practices.rst +++ b/doc/source/guidelines/dev_practices.rst @@ -115,7 +115,8 @@ For information specific to writing Pythonic error messages, see: - `Python Exception Handling `_ - `7 Tips to Improve Your Error Handling in Python `_ -- `Python Exception TUtorial: Printing Error Messges `_ + +Additionally, ensure that you have reviewed this guide's :ref:`logging` topic. Spelling and Code Style ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/guidelines/doc_practices.rst b/doc/source/guidelines/doc_practices.rst index de8f64f10..4c425a966 100644 --- a/doc/source/guidelines/doc_practices.rst +++ b/doc/source/guidelines/doc_practices.rst @@ -53,7 +53,7 @@ across PyAnsys libraries. For more information, see :ref:`api_documentation`. RST Files ~~~~~~~~~ To provide general usage information in your documentation, use your favorite editor to -create RST files that you then place in the repository's ``doc\`` directory. The ``index.rst`` +create RST files that you then place in the repository's ``doc`` directory. The ``index.rst`` file in the ``doc\source`` directory defines the first level of your documentation hierarchy. The ``toctree`` directive indicates the maximum number of heading levels that the documentation is to display. Below this directive are the directory names for your documentation sections. @@ -187,7 +187,7 @@ To use Windows PowerShell to clone a GitHub repository: Using GitBash to Clone a GitHub Repository ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To use GitBase to clone a GitHub repository: +To use GitBash to clone a GitHub repository: #. In the directory where you want to clone PyAnsys repositories, right-click and select ``GitBash Here``. @@ -342,7 +342,8 @@ and running. Installing Build Requirements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can build documentation for the ``dev_guide`` and ``pyansys-sphinx-theme`` repositories without +You can build documentation for the `dev_guide `_ +and `pyansys-sphinx-theme `_ repositories without installing a PyAnsys library in development mode. However, when you push changes that you have made in a local branch to the GitHub repository for other PyAnsys libraries, CI checks typically require that the full library is installed. @@ -376,7 +377,7 @@ that the full library is installed. .\make.bat html - As Sphinx is generating HTML output in the library's ``..\doc\_build\html`` folder, + As Sphinx is generating HTML output in the library's ``../doc/_build/html`` directory, Anaconda Powershell displays any errors and warnings for unexpected indentations, bad target locations for links, missing files, and extra files included in the repository but not referenced by any ``index.rst`` file. @@ -411,7 +412,7 @@ locally: updates. #. Install the latest version of Strawbery Perl, which enables you to build LaTeX files, accepting the default installation location (``C:\Strawberry\``). -#. In the Command Prompt window, type ``perl-v`` to test that you installation is +#. In the Command Prompt window, type ``perl-v`` to test that your installation is successful. #. Ensure that these Perl directory locations have been added to your ``Path`` system environment variable: From 2b4c92f342673e905843ada04b02312bd6517220 Mon Sep 17 00:00:00 2001 From: Kathy Pippert <84872299+PipKat@users.noreply.github.com> Date: Thu, 10 Feb 2022 12:18:11 -0500 Subject: [PATCH 4/7] Apply suggestions from code review Add Linux PDF build link Co-authored-by: Alex Kaszynski --- doc/source/guidelines/doc_practices.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/guidelines/doc_practices.rst b/doc/source/guidelines/doc_practices.rst index 4c425a966..1a38ee773 100644 --- a/doc/source/guidelines/doc_practices.rst +++ b/doc/source/guidelines/doc_practices.rst @@ -401,8 +401,8 @@ by creating a PR. For more information, see :ref:`create_pr`. Building a PDF of Your Documentation Locally -------------------------------------------- Some libraries supply a link to a PDF of the documentation under 'Assets' in the -release notes for a version. On Linux, building this PDF can be set up as an -automated process. On Windows, building a PDF is a manual process that you run +release notes for a version. On Linux, building this PDF can be done by following +`these directions . On Windows, building a PDF is a manual process that you run locally: #. Install `MiKTeX `_ for Windows, selecting the From 6a2b3a6db582b9652dcd5626b4d97341faf8cd08 Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Thu, 10 Feb 2022 12:33:03 -0500 Subject: [PATCH 5/7] Incorporate review comments --- doc/source/guidelines/doc_practices.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/source/guidelines/doc_practices.rst b/doc/source/guidelines/doc_practices.rst index 1a38ee773..1b6e8ee4d 100644 --- a/doc/source/guidelines/doc_practices.rst +++ b/doc/source/guidelines/doc_practices.rst @@ -114,9 +114,9 @@ repository. All of these examples, which should be PEP 8-compliant, are compiled during the build process. Always ensure that your examples run properly locally because they will be verified through the CI performed via GitHub Actions. -Adding a new standalone example consists of placing it in an applicable subfolder in the ``examples`` +Adding a new standalone example consists of placing it in an applicable subdirectory in the ``examples`` directory. If none of the existing directories match the category of your example, create -a new subfolder with a ``README.txt`` file describing the new category. Because these examples +a new subdirectory with a ``README.txt`` file describing the new category. Because these examples are built using the `Sphinx-Gallery `_ extension, you must follow its `coding guidelines `_. @@ -179,8 +179,7 @@ To use Windows PowerShell to clone a GitHub repository: #. Press ``Enter`` to copy the files in the repository to your local directory. -#. Type ``ls`` to see a list of the files now in the folder for this repository - in your local directory. +#. Type ``ls`` to see a list of the files now in your local directory. .. note:: In Anaconda Powershell, typing ``dir`` is the equivalent to typing ``ls``. @@ -338,7 +337,8 @@ and running. #. Clone the PyAnsys library's GitHub repository. For more information, see :ref:`cloning`. -#. If you have not yet cloned the ``pyansys-sphinx-theme`` repository, clone it. +#. If you have not yet cloned the `pyansys-sphinx-theme `_ + repository, clone it. Installing Build Requirements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From a159385af6ed9109ad1fa91133b9bbb7f2f78047 Mon Sep 17 00:00:00 2001 From: Kathy Pippert <84872299+PipKat@users.noreply.github.com> Date: Thu, 10 Feb 2022 12:33:52 -0500 Subject: [PATCH 6/7] Update doc/source/guidelines/doc_practices.rst --- doc/source/guidelines/doc_practices.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/guidelines/doc_practices.rst b/doc/source/guidelines/doc_practices.rst index 1a38ee773..51128bbac 100644 --- a/doc/source/guidelines/doc_practices.rst +++ b/doc/source/guidelines/doc_practices.rst @@ -338,7 +338,7 @@ and running. #. Clone the PyAnsys library's GitHub repository. For more information, see :ref:`cloning`. -#. If you have not yet cloned the ``pyansys-sphinx-theme`` repository, clone it. +#. If you have not yet cloned the `pyansys-sphinx-theme `_ repository, clone it. Installing Build Requirements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From a84b750e95f6a72bc779253bae6385843db3b765 Mon Sep 17 00:00:00 2001 From: Kathy Pippert Date: Thu, 10 Feb 2022 12:36:20 -0500 Subject: [PATCH 7/7] Fix missing end-string --- doc/source/guidelines/doc_practices.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/guidelines/doc_practices.rst b/doc/source/guidelines/doc_practices.rst index 1b6e8ee4d..1367c47eb 100644 --- a/doc/source/guidelines/doc_practices.rst +++ b/doc/source/guidelines/doc_practices.rst @@ -402,8 +402,8 @@ Building a PDF of Your Documentation Locally -------------------------------------------- Some libraries supply a link to a PDF of the documentation under 'Assets' in the release notes for a version. On Linux, building this PDF can be done by following -`these directions . On Windows, building a PDF is a manual process that you run -locally: +`these directions `_. +On Windows, building a PDF is a manual process that you run locally: #. Install `MiKTeX `_ for Windows, selecting the recommended option for installing it for only your own use.