Skip to content

Commit ffa2f41

Browse files
authored
Allow update of dpf-site.zip (#1379)
* Add update_virtual_environment_for_custom_operators in custom_operator.py (WIP) Signed-off-by: paul.profizi <[email protected]> * Add logic (WIP) Signed-off-by: paul.profizi <[email protected]> * Working version Signed-off-by: paul.profizi <[email protected]> * Working version Signed-off-by: paul.profizi <[email protected]> * Fix QA Signed-off-by: paul.profizi <[email protected]> --------- Signed-off-by: paul.profizi <[email protected]>
1 parent 8a59fb2 commit ffa2f41

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

src/ansys/dpf/core/custom_operator.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88

99
import abc
1010
import ctypes
11+
import os
12+
import pathlib
13+
import shutil
14+
import warnings
15+
import zipfile
16+
1117
import numpy
1218
import traceback
1319

@@ -31,6 +37,65 @@
3137
from ansys.dpf.gate import object_handler, capi, dpf_vector, integral_types
3238

3339

40+
def update_virtual_environment_for_custom_operators(restore_original: bool = False):
41+
"""Updates the dpf-site.zip file used to start a venv for Python custom operators to run in.
42+
43+
It updates the site-packages in dpf-site.zip with the site-packages of the current venv.
44+
It stores the original dpf-site.zip for future restoration.
45+
46+
.. note::
47+
This feature is only available InProcess to ensure compatibility of the current venv
48+
client-side with the machine where the server is run.
49+
50+
Parameters
51+
----------
52+
restore_original:
53+
If ``True``, restores the original dpf-site.zip.
54+
"""
55+
# Get the path to the dpf-site.zip in the current DPF server
56+
server = dpf.server.get_or_create_server(dpf.SERVER)
57+
if server.has_client():
58+
raise NotImplementedError(
59+
"Updating the dpf-site.zip of a DPF Server is only available when InProcess."
60+
)
61+
current_dpf_site_zip_path = os.path.join(server.ansys_path, "dpf", "python", "dpf-site.zip")
62+
# Get the path to where we store the original dpf-site.zip
63+
original_dpf_site_zip_path = os.path.join(
64+
server.ansys_path, "dpf", "python", "original", "dpf-site.zip"
65+
)
66+
# Restore the original dpf-site.zip
67+
if restore_original:
68+
if os.path.exists(original_dpf_site_zip_path):
69+
shutil.move(src=original_dpf_site_zip_path, dst=current_dpf_site_zip_path)
70+
os.rmdir(os.path.dirname(original_dpf_site_zip_path))
71+
else:
72+
warnings.warn("No original dpf-site.zip found. Current is most likely the original.")
73+
else:
74+
# Get the current paths to site_packages
75+
import site
76+
paths_to_current_site_packages = site.getsitepackages()
77+
current_site_packages_path = None
78+
# Get the first one targeting an actual site-packages folder
79+
for path_to_site_packages in paths_to_current_site_packages:
80+
if path_to_site_packages[-13:] == "site-packages":
81+
current_site_packages_path = pathlib.Path(path_to_site_packages)
82+
break
83+
if current_site_packages_path is None:
84+
warnings.warn("Could not find a currently loaded site-packages folder to update from.")
85+
return
86+
# Store original dpf-site.zip for this DPF Server if no original is stored
87+
if not os.path.exists(os.path.dirname(original_dpf_site_zip_path)):
88+
os.mkdir(os.path.dirname(original_dpf_site_zip_path))
89+
shutil.move(src=current_dpf_site_zip_path, dst=original_dpf_site_zip_path)
90+
# Zip the current site-packages at the destination
91+
with zipfile.ZipFile(current_dpf_site_zip_path, mode="w") as archive:
92+
for file_path in current_site_packages_path.rglob("*"):
93+
archive.write(
94+
filename=file_path,
95+
arcname=file_path.relative_to(current_site_packages_path)
96+
)
97+
98+
3499
def record_operator(operator_type, *args) -> None:
35100
"""
36101
Add an operator (with its name, run callback, and specification) to the DPF core registry.

0 commit comments

Comments
 (0)