Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* [Kathy Pippert](https://github.com/PipKat)
* [Maxime Rey](https://github.com/MaxJPRey)
* [Minsi Sung](https://github.com/ansminsisung)
* [Mohammad Zandsalimy](https://github.com/mozandsal)
* [Roberto Pastor Muela](https://github.com/RobPasMue)
* [SitaRamesh](https://github.com/SitaRamesh)
* [SriniSundararajan](https://github.com/SriniSundararajan)
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ dependencies = [
"protobuf>=3.19.3,<7",
"grpcio>=1.44.0",
"Django>=4.2.16",
"ansys-tools-common>=0.3.1"
"ansys-tools-common>=0.3.1",
"shapely==2.1.2"
]

[project.urls]
Expand Down
80 changes: 80 additions & 0 deletions src/ansys/edb/core/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""Configuration management for pyedb-core."""
from enum import Enum
import os


class ComputationBackend(Enum):
"""Computation backend options for geometry operations."""

SERVER = "server" # Use RPC server
SHAPELY = "shapely" # Use Shapely library
AUTO = "auto" # Auto-select: prefer server


class Config:
"""Global configuration for pyedb-core.

Configuration can be set via environment variables or programmatically.
CAUTION: if you are setting the backend programmatically by calling
``Config.set_computation_backend()``, the ``Config.reset()`` method is called
automatically to clear any previous settings. However, if you set the backend
via the environment variable ``PYEDB_COMPUTATION_BACKEND``, you need to call
``Config.reset()`` manually to ensure the new setting is applied.

Environment Variables:
PYEDB_COMPUTATION_BACKEND: Set to 'server', 'shapely', or 'auto' (default: 'auto')

Examples:
>>> # Set via environment variable (before importing)
>>> import os
>>> Config.reset() # Clear previous settings
>>> os.environ['PYEDB_COMPUTATION_BACKEND'] = 'shapely'

>>> # Set programmatically
>>> from ansys.edb.core.config import Config, ComputationBackend
>>> Config.set_computation_backend(ComputationBackend.SHAPELY)
"""

_computation_backend: ComputationBackend = None

@classmethod
def get_computation_backend(cls) -> ComputationBackend:
"""Get the current computation backend setting.

Returns
-------
ComputationBackend
The configured computation backend.
"""
if cls._computation_backend is None:
env_value = os.getenv("PYEDB_COMPUTATION_BACKEND", "auto").lower()
try:
cls._computation_backend = ComputationBackend(env_value)
except ValueError:
cls._computation_backend = ComputationBackend.AUTO

return cls._computation_backend

@classmethod
def set_computation_backend(cls, backend: ComputationBackend | str):
"""Set the computation backend.

Parameters
----------
backend : ComputationBackend or str
The backend to use for geometry computations.
Can be 'server', 'shapely', or 'auto'.

Examples:
>>> Config.set_computation_backend(ComputationBackend.SHAPELY)
>>> Config.set_computation_backend('shapely')
"""
cls.reset()
if isinstance(backend, str):
backend = ComputationBackend(backend.lower())
cls._computation_backend = backend

@classmethod
def reset(cls):
"""Reset configuration to defaults (useful for testing)."""
cls._computation_backend = None
6 changes: 6 additions & 0 deletions src/ansys/edb/core/geometry/backends/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""Geometry computation backends."""

from ansys.edb.core.geometry.backends.backend_factory import get_backend
from ansys.edb.core.geometry.backends.base import PolygonBackend

__all__ = ["PolygonBackend", "get_backend"]
101 changes: 101 additions & 0 deletions src/ansys/edb/core/geometry/backends/backend_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""Factory for creating the appropriate polygon computation backend."""

from __future__ import annotations

from ansys.edb.core.config import ComputationBackend, Config
from ansys.edb.core.geometry.backends.base import PolygonBackend


def get_backend(stub=None) -> PolygonBackend:
"""Get the appropriate polygon computation backend based on configuration.

Parameters
----------
stub : polygon_data_pb2_grpc.PolygonDataServiceStub, optional
The gRPC stub for polygon operations. Required for server backend.

Returns
-------
PolygonBackend
The configured computation backend.

Notes
-----
The backend is selected based on the PYEDB_COMPUTATION_BACKEND environment
variable or the programmatic configuration. The selection logic is:

- 'server': Always use server backend
- 'shapely': Use Shapely backend (raises error if not installed)
- 'auto' (default): Try Shapely first, fallback to server if not available

Examples
--------
>>> # Use server backend explicitly
>>> import os
>>> os.environ['PYEDB_COMPUTATION_BACKEND'] = 'server'
>>> backend = get_backend(stub)

>>> # Use Shapely backend
>>> from ansys.edb.core.config import Config, ComputationBackend
>>> Config.set_computation_backend(ComputationBackend.SHAPELY)
>>> backend = get_backend()
"""
backend_type = Config.get_computation_backend()

if backend_type == ComputationBackend.SERVER:
return _get_server_backend(stub)

elif backend_type == ComputationBackend.SHAPELY:
return _get_shapely_backend(stub)

elif backend_type == ComputationBackend.AUTO:
# Use server backend by default
return _get_server_backend(stub)

else:
raise ValueError(f"Unknown backend type: {backend_type}")


def _get_server_backend(stub) -> PolygonBackend:
"""Get the server backend instance.

Parameters
----------
stub : polygon_data_pb2_grpc.PolygonDataServiceStub
The gRPC stub for polygon operations.

Returns
-------
ServerBackend
Server computation backend.
"""
if stub is None:
raise ValueError("Server backend requires a stub parameter")

from ansys.edb.core.geometry.backends.server_backend import ServerBackend

return ServerBackend(stub)


def _get_shapely_backend(stub=None) -> PolygonBackend:
"""Get the Shapely backend instance.

Parameters
----------
stub : polygon_data_pb2_grpc.PolygonDataServiceStub, optional
The gRPC stub for polygon operations. Passed to ShapelyBackend for
methods that delegate to the server backend (e.g., alpha_shape).

Returns
-------
ShapelyBackend
Shapely computation backend.

Raises
------
ImportError
If Shapely is not installed.
"""
from ansys.edb.core.geometry.backends.shapely_backend import ShapelyBackend

return ShapelyBackend(stub)
Loading
Loading