From c6319dd1a3695e52d5a18f68976f0e28b998ad86 Mon Sep 17 00:00:00 2001 From: Mainak Kundu Date: Mon, 2 Dec 2024 18:34:12 -0500 Subject: [PATCH 1/4] docs: event streaming callback --- doc/source/conf.py | 12 +++++------ doc/source/user_guide/events.rst | 21 ++++++++++++------- .../streaming_services/events_streaming.py | 13 ++++++++++++ 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 1ed05a26c3a..ed33047dbcd 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -197,12 +197,12 @@ def _stop_fluent_container(gallery_conf, fname): "navbar_end": ["version-switcher", "theme-switcher", "navbar-icon-links"], "navigation_depth": -1, "collapse_navigation": True, - "cheatsheet": { - "file": "cheatsheet/cheat_sheet.qmd", - "pages": ["index", "getting_started/index", "user_guide/index"], - "title": "PyFluent cheat sheet", - "version": __version__, - }, + # "cheatsheet": { + # "file": "cheatsheet/cheat_sheet.qmd", + # "pages": ["index", "getting_started/index", "user_guide/index"], + # "title": "PyFluent cheat sheet", + # "version": __version__, + # }, } # -- Options for HTMLHelp output --------------------------------------------- diff --git a/doc/source/user_guide/events.rst b/doc/source/user_guide/events.rst index d38879b01c1..5616bad1d95 100644 --- a/doc/source/user_guide/events.rst +++ b/doc/source/user_guide/events.rst @@ -18,13 +18,19 @@ The following code triggers a callback at the end of every iteration. .. code-block:: python - >>> from ansys.fluent.core import SolverEvent + >>> from ansys.fluent.core import SolverEvent, IterationEndedEventInfo >>> - >>> def on_iteration_ended(session, event_info): + >>> def on_iteration_ended(session, event_info: IterationEndedEventInfo): >>> print("Iteration ended. Index = ", event_info.index) >>> >>> callback_id = solver.events.register_callback(SolverEvent.ITERATION_ENDED, on_iteration_ended) - >>> + +The general signature of the callback function is cb(\*args, session, event_info), where session is the session instance +and event_info instance holds information about the event. The event_info classes for each event are documented in the +API reference of the :obj:`~ansys.fluent.core.streaming_services.events_streaming` module. See the callback function +on_case_loaded_with_args() in the below examples for an example of how to pass additional arguments to the callback +function via the args parameter. + Examples -------- @@ -32,6 +38,7 @@ Examples .. code-block:: python >>> from ansys.fluent.core import MeshingEvent, SolverEvent + >>> from ansys.fluent.core import CaseLoadedEventInfo, DataLoadedEventInfo, SolutionInitializedEventInfo, IterationEndedEventInfo >>> from ansys.fluent.core.utils.event_loop import execute_in_event_loop_threadsafe >>> from ansys.fluent.visualization.matplotlib import matplot_windows_manager >>> from ansys.fluent.visualization.pyvista import pyvista_windows_manager @@ -48,7 +55,7 @@ Examples >>> contour2.surfaces_list = ["symmetry"] >>> >>> @execute_in_event_loop_threadsafe - >>> def auto_refersh_call_back_iteration(session, event_info): + >>> def auto_refersh_call_back_iteration(session, event_info: IterationEndedEventInfo): >>> if event_info.index % 5 == 0: >>> pyvista_windows_manager.refresh_windows(session.id, ["contour-1", "contour-2"]) >>> matplot_windows_manager.refresh_windows("", ["residual"]) @@ -56,7 +63,7 @@ Examples >>> callback_itr_id = solver.events.register_callback(SolverEvent.ITERATION_ENDED, auto_refersh_call_back_iteration) >>> >>> @execute_in_event_loop_threadsafe - >>> def initialize_call_back(session, event_info): + >>> def initialize_call_back(session, event_info: SolutionInitializedEventInfo | DataLoadedEventInfo): >>> pyvista_windows_manager.refresh_windows(session.id, ["contour-1", "contour-2"]) >>> matplot_windows_manager.refresh_windows("", ["residual"]) >>> @@ -64,10 +71,10 @@ Examples >>> >>> callback_data_read_id = solver.events.register_callback(SolverEvent.DATA_LOADED, initialize_call_back) >>> - >>> def on_case_loaded(session, event_info): + >>> def on_case_loaded(session, event_info: CaseLoadedEventInfo): >>> print("Case loaded. Index = ", event_info.index) >>> - >>> def on_case_loaded_with_args(x, y, session, event_info): + >>> def on_case_loaded_with_args(x, y, session, event_info: CaseLoadedEventInfo): >>> print(f"Case loaded with {x}, {y}. Index = ", event_info.index) >>> >>> callback = meshing.events.register_callback(MeshingEvent.CASE_LOADED, on_case_loaded) diff --git a/src/ansys/fluent/core/streaming_services/events_streaming.py b/src/ansys/fluent/core/streaming_services/events_streaming.py index 1d73b02c6aa..bc8e4fca81a 100644 --- a/src/ansys/fluent/core/streaming_services/events_streaming.py +++ b/src/ansys/fluent/core/streaming_services/events_streaming.py @@ -128,6 +128,7 @@ def __getattr__(self, name): @dataclass class TimestepStartedEventInfo(EventInfoBase, event=SolverEvent.TIMESTEP_STARTED): """Information about the event triggered when a timestep is started. + Attributes ---------- index : int @@ -143,6 +144,7 @@ class TimestepStartedEventInfo(EventInfoBase, event=SolverEvent.TIMESTEP_STARTED @dataclass class TimestepEndedEventInfo(EventInfoBase, event=SolverEvent.TIMESTEP_ENDED): """Information about the event triggered when a timestep is ended. + Attributes ---------- index : int @@ -158,6 +160,7 @@ class TimestepEndedEventInfo(EventInfoBase, event=SolverEvent.TIMESTEP_ENDED): @dataclass class IterationEndedEventInfo(EventInfoBase, event=SolverEvent.ITERATION_ENDED): """Information about the event triggered when an iteration is ended. + Attributes ---------- index : int @@ -190,6 +193,7 @@ class CalculationsResumedEventInfo( @dataclass class AboutToLoadCaseEventInfo(EventInfoBase, event=SolverEvent.ABOUT_TO_LOAD_CASE): """Information about the event triggered just before a case file is loaded. + Attributes ---------- case_file_name : str @@ -202,6 +206,7 @@ class AboutToLoadCaseEventInfo(EventInfoBase, event=SolverEvent.ABOUT_TO_LOAD_CA @dataclass class CaseLoadedEventInfo(EventInfoBase, event=SolverEvent.CASE_LOADED): """Information about the event triggered after a case file is loaded. + Attributes ---------- case_file_name : str @@ -214,6 +219,7 @@ class CaseLoadedEventInfo(EventInfoBase, event=SolverEvent.CASE_LOADED): @dataclass class AboutToLoadDataEventInfo(EventInfoBase, event=SolverEvent.ABOUT_TO_LOAD_DATA): """Information about the event triggered just before a data file is loaded. + Attributes ---------- data_file_name : str @@ -226,6 +232,7 @@ class AboutToLoadDataEventInfo(EventInfoBase, event=SolverEvent.ABOUT_TO_LOAD_DA @dataclass class DataLoadedEventInfo(EventInfoBase, event=SolverEvent.DATA_LOADED): """Information about the event triggered after a data file is loaded. + Attributes ---------- data_file_name : str @@ -252,6 +259,7 @@ class ReportDefinitionUpdatedEventInfo( EventInfoBase, event=SolverEvent.REPORT_DEFINITION_UPDATED ): """Information about the event triggered when a report definition is updated. + Attributes ---------- report_name : str @@ -266,6 +274,7 @@ class ReportPlotSetUpdatedEventInfo( EventInfoBase, event=SolverEvent.REPORT_PLOT_SET_UPDATED ): """Information about the event triggered when a report plot set is updated. + Attributes ---------- plot_set_name : str @@ -288,6 +297,7 @@ class SettingsClearedEventInfo(EventInfoBase, event=SolverEvent.SETTINGS_CLEARED @dataclass class SolutionPausedEventInfo(EventInfoBase, event=SolverEvent.SOLUTION_PAUSED): """Information about the event triggered when solution is paused. + Attributes ---------- level : str @@ -303,6 +313,7 @@ class SolutionPausedEventInfo(EventInfoBase, event=SolverEvent.SOLUTION_PAUSED): @dataclass class ProgressUpdatedEventInfo(EventInfoBase, event=SolverEvent.PROGRESS_UPDATED): """Information about the event triggered when progress is updated. + Attributes ---------- message : str @@ -320,6 +331,7 @@ class SolverTimeEstimateUpdatedEventInfo( EventInfoBase, event=SolverEvent.SOLVER_TIME_ESTIMATE_UPDATED ): """Information about the event triggered when solver time estimate is updated. + Attributes ---------- hours : float @@ -338,6 +350,7 @@ class SolverTimeEstimateUpdatedEventInfo( @dataclass class FatalErrorEventInfo(EventInfoBase, event=SolverEvent.FATAL_ERROR): """Information about the event triggered when a fatal error occurs. + Attributes ---------- message : str From 7b27d14c6ca04a52674c4c11b93f6949a663977d Mon Sep 17 00:00:00 2001 From: Mainak Kundu Date: Mon, 2 Dec 2024 18:57:39 -0500 Subject: [PATCH 2/4] docs: event streaming callback --- doc/source/conf.py | 19 +++++++++---------- .../contributing/environment_variables.rst | 6 ++++-- doc/source/user_guide/events.rst | 8 ++++---- .../streaming_services/events_streaming.py | 1 + 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index ed33047dbcd..0b7fbbdd122 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -42,10 +42,7 @@ toggleprompt_offset_right = 35 -skip_examples = int(os.getenv("PYFLUENT_SKIP_EXAMPLES_DOC", 0)) -if skip_examples: - pass -else: +if os.getenv("PYFLUENT_DOC_SKIP_EXAMPLES") != "1": extensions.append("sphinx_gallery.gen_gallery") typehints_document_rtype = False @@ -197,14 +194,16 @@ def _stop_fluent_container(gallery_conf, fname): "navbar_end": ["version-switcher", "theme-switcher", "navbar-icon-links"], "navigation_depth": -1, "collapse_navigation": True, - # "cheatsheet": { - # "file": "cheatsheet/cheat_sheet.qmd", - # "pages": ["index", "getting_started/index", "user_guide/index"], - # "title": "PyFluent cheat sheet", - # "version": __version__, - # }, } +if os.getenv("PYFLUENT_DOC_SKIP_CHEATSHEET") != "1": + html_theme_options["cheatsheet"] = { + "file": "cheatsheet/cheat_sheet.qmd", + "pages": ["index", "getting_started/index", "user_guide/index"], + "title": "PyFluent cheat sheet", + "version": __version__, + } + # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. diff --git a/doc/source/contributing/environment_variables.rst b/doc/source/contributing/environment_variables.rst index 75b47d6edd2..280b2b1505d 100644 --- a/doc/source/contributing/environment_variables.rst +++ b/doc/source/contributing/environment_variables.rst @@ -29,6 +29,10 @@ Following is a list of environment variables that can be set to control various - Specifies the path inside the container where the host path is mounted while starting a Fluent container in :func:`launch_fluent() `. * - PYFLUENT_FLUENT_DEBUG - Starts Fluent in debug mode while launching Fluent in :func:`launch_fluent() `. + * - PYFLUENT_DOC_SKIP_CHEATSHEET: + - Skips the generation of cheatsheet. + * - PYFLUENT_DOC_SKIP_EXAMPLES + - Skips the generation of examples documentation. * - PYFLUENT_FLUENT_IP - Specifies the IP address of the Fluent server in :func:`connect_to_fluent() `. * - PYFLUENT_FLUENT_PORT @@ -47,8 +51,6 @@ Following is a list of environment variables that can be set to control various - Shows the Fluent GUI while launching Fluent in :func:`launch_fluent() `. * - PYFLUENT_SKIP_API_UPGRADE_ADVICE - Disables printing of TUI to settings API upgrade advice. - * - PYFLUENT_SKIP_EXAMPLES_DOC - - Skips the generation of examples documentation. * - PYFLUENT_TIMEOUT_FORCE_EXIT - Enables force exit while exiting a Fluent session and specifies the timeout in seconds. * - PYFLUENT_WATCHDOG_DEBUG diff --git a/doc/source/user_guide/events.rst b/doc/source/user_guide/events.rst index 5616bad1d95..a8afb9b835d 100644 --- a/doc/source/user_guide/events.rst +++ b/doc/source/user_guide/events.rst @@ -25,11 +25,11 @@ The following code triggers a callback at the end of every iteration. >>> >>> callback_id = solver.events.register_callback(SolverEvent.ITERATION_ENDED, on_iteration_ended) -The general signature of the callback function is cb(\*args, session, event_info), where session is the session instance -and event_info instance holds information about the event. The event_info classes for each event are documented in the +The general signature of the callback function is ``cb(, session, event_info)``, where ``session`` is the session instance +and ``event_info`` instance holds information about the event. The event information classes for each event are documented in the API reference of the :obj:`~ansys.fluent.core.streaming_services.events_streaming` module. See the callback function -on_case_loaded_with_args() in the below examples for an example of how to pass additional arguments to the callback -function via the args parameter. +``on_case_loaded_with_args()`` in the below examples for an example of how to pass optional arguments to the callback +function. Examples diff --git a/src/ansys/fluent/core/streaming_services/events_streaming.py b/src/ansys/fluent/core/streaming_services/events_streaming.py index bc8e4fca81a..b5ce2637e77 100644 --- a/src/ansys/fluent/core/streaming_services/events_streaming.py +++ b/src/ansys/fluent/core/streaming_services/events_streaming.py @@ -16,6 +16,7 @@ from ansys.fluent.core.warnings import PyFluentDeprecationWarning __all__ = [ + "EventsManager", "Event", "SolverEvent", "MeshingEvent", From 18e6e6dcdab0e3e41a233cb4d9dc626f99bb0644 Mon Sep 17 00:00:00 2001 From: Mainak Kundu Date: Mon, 2 Dec 2024 22:54:40 -0500 Subject: [PATCH 3/4] feat: optional last --- doc/source/user_guide/events.rst | 6 ++--- .../streaming_services/events_streaming.py | 25 +++++++++++-------- tests/test_events_manager.py | 13 +++++++++- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/doc/source/user_guide/events.rst b/doc/source/user_guide/events.rst index a8afb9b835d..1bd18e53a0b 100644 --- a/doc/source/user_guide/events.rst +++ b/doc/source/user_guide/events.rst @@ -25,10 +25,10 @@ The following code triggers a callback at the end of every iteration. >>> >>> callback_id = solver.events.register_callback(SolverEvent.ITERATION_ENDED, on_iteration_ended) -The general signature of the callback function is ``cb(, session, event_info)``, where ``session`` is the session instance +The general signature of the callback function is ``cb(session, event_info, )``, where ``session`` is the session instance and ``event_info`` instance holds information about the event. The event information classes for each event are documented in the API reference of the :obj:`~ansys.fluent.core.streaming_services.events_streaming` module. See the callback function -``on_case_loaded_with_args()`` in the below examples for an example of how to pass optional arguments to the callback +``on_case_loaded_with_args()`` in the below examples for an example of how to pass additional arguments to the callback function. @@ -74,7 +74,7 @@ Examples >>> def on_case_loaded(session, event_info: CaseLoadedEventInfo): >>> print("Case loaded. Index = ", event_info.index) >>> - >>> def on_case_loaded_with_args(x, y, session, event_info: CaseLoadedEventInfo): + >>> def on_case_loaded_with_args(session, event_info: CaseLoadedEventInfo, x, y): >>> print(f"Case loaded with {x}, {y}. Index = ", event_info.index) >>> >>> callback = meshing.events.register_callback(MeshingEvent.CASE_LOADED, on_case_loaded) diff --git a/src/ansys/fluent/core/streaming_services/events_streaming.py b/src/ansys/fluent/core/streaming_services/events_streaming.py index b5ce2637e77..0c48c15511f 100644 --- a/src/ansys/fluent/core/streaming_services/events_streaming.py +++ b/src/ansys/fluent/core/streaming_services/events_streaming.py @@ -442,23 +442,26 @@ def _process_streaming( @staticmethod def _make_callback_to_call(callback: Callable, args, kwargs): - old_style = "session_id" in inspect.signature(callback).parameters - if old_style: + params = inspect.signature(callback).parameters + if "session_id" in params: warnings.warn( "Update event callback function signatures" " substituting 'session' for 'session_id'.", PyFluentDeprecationWarning, ) - fn = partial(callback, *args, **kwargs) - return ( - ( - lambda session, event_info: fn( - session_id=session.id, event_info=event_info - ) + return lambda session, event_info: callback( + *args, session_id=session.id, event_info=event_info, **kwargs + ) + else: + positional_args = [ + p + for p in params + if p not in kwargs and p not in ("session", "event_info") + ] + kwargs.update(dict(zip(positional_args, args))) + return lambda session, event_info: callback( + session=session, event_info=event_info, **kwargs ) - if old_style - else fn - ) def register_callback( self, diff --git a/tests/test_events_manager.py b/tests/test_events_manager.py index 925ed39de3e..fea1b35b067 100644 --- a/tests/test_events_manager.py +++ b/tests/test_events_manager.py @@ -28,7 +28,12 @@ def on_case_loaded(session, event_info): on_case_loaded.loaded = False - def on_case_loaded_with_args(x, y, session, event_info): + def on_case_loaded_with_args_optional_first(x, y, session, event_info): + on_case_loaded_with_args_optional_first.state = dict(x=x, y=y) + + on_case_loaded_with_args_optional_first.state = None + + def on_case_loaded_with_args(session, event_info, x, y): on_case_loaded_with_args.state = dict(x=x, y=y) on_case_loaded_with_args.state = None @@ -43,6 +48,10 @@ def on_case_loaded_with_args(x, y, session, event_info): solver.events.register_callback(SolverEvent.CASE_LOADED, on_case_loaded) + solver.events.register_callback( + SolverEvent.CASE_LOADED, on_case_loaded_with_args_optional_first, 12, y=42 + ) + solver.events.register_callback( SolverEvent.CASE_LOADED, on_case_loaded_with_args, 12, y=42 ) @@ -54,6 +63,7 @@ def on_case_loaded_with_args(x, y, session, event_info): assert not on_case_loaded_old.loaded assert not on_case_loaded.loaded assert not on_case_loaded_old_with_args.state + assert not on_case_loaded_with_args_optional_first.state assert not on_case_loaded_with_args.state try: @@ -64,6 +74,7 @@ def on_case_loaded_with_args(x, y, session, event_info): assert on_case_loaded_old.loaded assert on_case_loaded.loaded assert on_case_loaded_old_with_args.state == dict(x=12, y=42) + assert on_case_loaded_with_args_optional_first.state == dict(x=12, y=42) assert on_case_loaded_with_args.state == dict(x=12, y=42) From a75b945062a1f0d5333da6c3eec08afcb5937422 Mon Sep 17 00:00:00 2001 From: Mainak Kundu Date: Tue, 3 Dec 2024 08:41:17 -0500 Subject: [PATCH 4/4] docs: move cheatsheet build to nightly --- .github/workflows/ci.yml | 17 +---------------- .github/workflows/doc-build-dev-nightly.yml | 16 ++++++++++++++++ .github/workflows/doc-build-release.yml | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 527477151ad..e45b1445b70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,22 +115,6 @@ jobs: restore-keys: | Python-${{ runner.os }}-${{ matrix.python-version }} - - name: Install Quarto - uses: quarto-dev/quarto-actions/setup@v2 - with: - tinytex: true - - - name: Check Quarto Version - shell: bash - run: | - quarto --version - - - name: "Install Poppler for PDF to PNG conversion" - shell: bash - run: | - sudo apt-get update - sudo apt-get install -y poppler-utils - - name: Install pyfluent run: make install @@ -197,6 +181,7 @@ jobs: make build-doc-source env: FLUENT_IMAGE_TAG: ${{ env.DOC_DEPLOYMENT_IMAGE_TAG }} + PYFLUENT_DOC_SKIP_CHEATSHEET: 1 - name: Zip HTML Documentation before upload run: | diff --git a/.github/workflows/doc-build-dev-nightly.yml b/.github/workflows/doc-build-dev-nightly.yml index d4ad51ec8c6..a5ae573e594 100644 --- a/.github/workflows/doc-build-dev-nightly.yml +++ b/.github/workflows/doc-build-dev-nightly.yml @@ -34,6 +34,22 @@ jobs: sudo apt update sudo apt-get install pandoc libegl1 make xvfb libfontconfig1 libxrender1 libxkbcommon-x11-0 -y + - name: Install Quarto + uses: quarto-dev/quarto-actions/setup@v2 + with: + tinytex: true + + - name: Check Quarto Version + shell: bash + run: | + quarto --version + + - name: "Install Poppler for PDF to PNG conversion" + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y poppler-utils + - name: Install pyfluent run: make install diff --git a/.github/workflows/doc-build-release.yml b/.github/workflows/doc-build-release.yml index b304b462253..62312889b8b 100644 --- a/.github/workflows/doc-build-release.yml +++ b/.github/workflows/doc-build-release.yml @@ -36,6 +36,22 @@ jobs: sudo apt update sudo apt-get install pandoc libegl1 make xvfb libfontconfig1 libxrender1 libxkbcommon-x11-0 -y + - name: Install Quarto + uses: quarto-dev/quarto-actions/setup@v2 + with: + tinytex: true + + - name: Check Quarto Version + shell: bash + run: | + quarto --version + + - name: "Install Poppler for PDF to PNG conversion" + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y poppler-utils + - name: Install pyfluent run: make install