Skip to content

feat: REST settings services - #5298

Draft
mayankansys wants to merge 33 commits into
mainfrom
feat/REST_settings
Draft

feat: REST settings services#5298
mayankansys wants to merge 33 commits into
mainfrom
feat/REST_settings

Conversation

@mayankansys

@mayankansys mayankansys commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Context

PyFluent previously supported communication with Fluent solvers exclusively through gRPC-based transport, which requires additional infrastructure and dependencies. There was a need to demonstrate that PyFluent can run seamlessly over both REST and gRPC, allowing users to choose their preferred transport mechanism.

Change Summary

This PR introduces comprehensive REST/HTTP transport support to PyFluent with the following key additions:

  • New RestSettings class — A settings service wrapper that implements the AbstractSettings interface by delegating all operations to a FluentRestClient instance. Includes schema normalization to convert REST's native hyphenated Scheme keys (e.g., object-type, user-creatable?) to underscore format matching gRPC conventions.

  • New HttpSolver class — A standalone, lightweight solver session that communicates exclusively over REST, completely independent of gRPC infrastructure. Settings classes are built at runtime from get_static_info() with no need for pre-generated modules.

  • Factory method — Convenience classmethod to create an HttpSolver instance from a URL and authentication token, making REST-based sessions accessible through the standard Solver interface.

  • Comprehensive tests — Unit and integration tests covering REST settings wildcard detection, static-info key normalization, nested schema recursion, and end-to-end REST-based workflows.

Rationale

  • Transport flexibility: REST/HTTP is stateless and works in cloud, containerized, and restricted network environment. It gives the user access to choose the REST/gRPC as required.
  • Runtime schema building: The HttpSolver derives settings structure dynamically from server responses via get_static_info(), eliminating the need for hand-maintained pre-generated settings modules.
  • API consistency: The RestSettings class implements AbstractSettings, ensuring compatibility with existing PyFluent abstractions designed for any settings transport backend.
  • Minimal dependencies: HttpSolver has no dependency on gRPC libraries or session management infrastructure, making it suitable for lightweight client applications.
  • Server compatibility: Available from Fluent 27.1 onward; client-side schema corrections handle known gaps in REST server responses.

Impact

  • User workflows: Users can now connect via REST using Solver.from_http(url, token), in addition to the existing gRPC-based Solver() constructors. Both transports coexist without interference.
  • Transparent operation: Existing code using the settings API (e.g., solver.settings.setup.models.energy.enabled()) works identically over REST and gRPC.
  • Testing: New REST fixtures enable testing on live Fluent 27.1+ REST servers, complementing existing gRPC-based test infrastructure (controlled via FLUENT_REST_URL and FLUENT_REST_TOKEN environment variables).
  • Schema normalization: Automatic conversion of REST's hyphenated schema keys to underscore format hides transport-specific details from downstream code.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Comment thread src/ansys/fluent/core/session_http_solver.py
Comment thread src/ansys/fluent/core/session_http_solver.py Outdated
Comment thread src/ansys/fluent/core/session_solver.py
Comment thread tests/test_settings_api.py Outdated
@prmukherj

Copy link
Copy Markdown
Collaborator

@mayankansys, in general you could just re-use our existing tests by just parameterizing them. You can avoid any kind of duplication via the adapters, etc. The tests should be the existing ones just by parameterizing them so as to avoid duplication. A few of the extra tests that you have written like over-writing named objects, etc. can be kept but similarly parameterize them for grpc as well.

Thank you.

Comment thread src/ansys/fluent/core/services/rest_settings.py Outdated
@prmukherj
prmukherj marked this pull request as ready for review August 18, 2026 13:18
Comment thread tests/test_settings_api.py Outdated
# Helpers for transport-parametrized tests (gRPC vs REST)
# ============================================================================


Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The settings API can be tested through either REST or gRPC interchangeably. Therefore, given any such API test, one can pass in any solver session object (or its settings attribute).

If you need all the following complications, please explain. Thanks.

Comment thread tests/test_settings_api.py Outdated
"option": "auto-range-off",
"auto_range_off": {
}
if isinstance(solver, HttpSolver):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use same as existing. Don't update paths as part of this PR.

Comment thread tests/conftest.py Outdated
# HttpSolver (REST transport) has no .exit()/close mechanism yet - guard
# so REST-parametrized tests don't fail during fixture teardown.
if hasattr(solver, "exit"):
solver.exit()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to incorporate the exit as part of this PR only, but we can do it as a last change after finalizing this PR with other changes first.

Comment thread tests/conftest.py
Comment thread tests/conftest.py Outdated
),
]
)
def new_solver_session(request):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a new one named "solver_session_grpc_rest", and use that for all the tests that needs to use the parameterized fixture testing both grpc and rest server. Keep the "new_solver_session" as it is.

Comment thread tests/test_session.py Outdated
from ansys.fluent.core.launcher.error_handler import LaunchFluentError
from ansys.fluent.core.pyfluent_warnings import PyFluentDeprecationWarning
from ansys.fluent.core.session import BaseSession
from ansys.fluent.core.session_http_solver import HttpSolver

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file will not require any changes after the comment on conftest is addressed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread tests/test_settings_api.py Outdated
Comment thread tests/test_session.py Outdated
pytest.skip(
"enable_beta_features()/get_fluent_version() are not applicable to REST transport"
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mayankansys

I prefer to simply define what is to be tested fully from the top without any internal conditional skipping. That provides a clean, well defined view of what is and is not covered.

This simple example gets the basic idea across by defining what is to be run from the top and contains no conditionals. It lets the code decide what happens.

# define a test function that only works with gRPC backend:
def do_test_some_solver_features(solver): # ...

# define the test only for gRPC:
def test_some_solver_features(grpc_solver_session):
    do_test_some_solver_features(grpc_solver_session)

# that inflates the test code so we can just do it in one go:
def test_some_solver_features(grpc_solver_session): # ...

# @pytest.mark is also possible above but unnecessary

# define a test function that works with either backend:
def do_test_some_other_solver_features(solver): # ...

# define both tests:
# gRPC:
def test_some_other_solver_features(grpc_solver_session):
    do_test_some_other_solver_features(grpc_solver_session)

# http:
def test_some_other_solver_features(http_solver_session):
    do_test_some_other_solver_features(http_solver_session)

# again, that inflates the test code so we can make use of parametrised fixture selection:
@pytest_fixture(params=...)
def solver_session(...)
    return { ...

# run the test with either backend, gRPC or http:
def test_some_other_solver_features(solver_session): # ...

@mkundu1 @prmukherj

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @seanpearsonuk, This is exactly what we should so.

@github-actions github-actions Bot added documentation Documentation related (improving, adding, etc) examples Publishing PyFluent examples maintenance General maintenance of the repo (libraries, cicd, etc) CI/CD labels Aug 31, 2026
- Drop the duplicated PyFluentDeprecationWarning import in session/solver.py (already covered by the grouped ansys.fluent.core.exceptions import).
- Sort the session imports in tests/test_settings_api.py.
- Remove function-local re-imports of Viscous and VelocityInlets that shadow the module-level import.
Commit a496ce5 (session_solver.py code moved to session_utilities) deleted the
from_http classmethod and its TYPE_CHECKING import of HttpSolver without adding
them anywhere else, leaving tests/conftest.py calling a method that no longer
existed.
The override added a third 'properties' argument that no caller supplies:
flobject calls flproxy.create(path, name) with two arguments only. REST now
inherits BaseSettings.create, matching the gRPC contract. FluentRestClient.create
still accepts 'properties' for direct client use.
@mayankansys
mayankansys marked this pull request as draft September 1, 2026 12:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD documentation Documentation related (improving, adding, etc) examples Publishing PyFluent examples maintenance General maintenance of the repo (libraries, cicd, etc) new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Demonstrate that PyFluent can run transparently over REST or gRPC for solver settings

4 participants