]> SALOME platform Git repositories - modules/kernel.git/blob - src/KERNEL_PY/__init__.py
Salome HOME
2467acb73cc4b7aa43117f04e76ff1aa6062abeb
[modules/kernel.git] / src / KERNEL_PY / __init__.py
1 #  -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
3 #
4 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
5 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20 #
21 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #
23
24 #  File   : salome.py renamed as __init__.py for python packaging (gboulant)
25 #  Author : Paul RASCLE, EDF
26 #  Module : SALOME
27 #
28 """ 
29 Module salome gives access to Salome resources.
30
31 variables:
32
33   - salome.orb             : CORBA
34   - salome.naming_service  : instance of naming Service class
35       - methods:
36           - Resolve(name)  : find a CORBA object (ior) by its pathname
37           - Register(name) : register a CORBA object under a pathname
38
39   - salome.lcc             : instance of lifeCycleCORBA class
40       - methods:
41           - FindOrLoadComponent(server,name) :
42                            obtain an Engine (CORBA object)
43                            or launch the Engine if not found,
44                            with a Server name and an Engine name
45
46   - salome.sg              : salome object to communicate with the graphical user interface (if any)
47       - methods:
48          - updateObjBrowser():
49
50          - SelectedCount():      returns number of selected objects
51          - getSelected(i):       returns entry of selected object number i
52          - getAllSelected():     returns list of entry of selected objects
53          - AddIObject(Entry):    select an existing Interactive object
54          - RemoveIObject(Entry): remove object from selection
55          - ClearIObjects():      clear selection
56
57          - Display(*Entry):
58          - DisplayOnly(Entry):
59          - Erase(Entry):
60          - DisplayAll():
61          - EraseAll():
62
63          - IDToObject(Entry):    returns CORBA reference from entry
64
65   - salome.myStudyName     : active Study Name
66   - salome.myStudy         : the active Study itself (CORBA ior)
67       - methods : defined in SALOMEDS.idl
68
69 """
70 ## @package salome
71 # Module salome gives access to Salome resources.
72 #
73 #  \param salome.orb             : CORBA orb object
74 #  \param salome.naming_service  : instance of naming Service class (SALOME_NamingServicePy::SALOME_NamingServicePy_i)
75 #  \param salome.lcc             : instance of lifeCycleCORBA class (SALOME_LifeCycleCORBA)
76 #  \param salome.sg              : Salome object to communicate with the graphical user interface, if running (see interface in salome_iapp::SalomeOutsideGUI)
77 #  \param salome.myStudyName     : active Study Name
78 #  \param salome.myStudy         : the active Study (interface SALOMEDS::Study)
79
80 #
81 # ==========================================================================
82 #
83 # The function extend_path is used here to aggregate in a single
84 # virtual python package all the python sub-packages embedded in each
85 # SALOME modules (python "namespace" pattern).
86 #
87 ROOT_PYTHONPACKAGE_NAME="salome"
88 #
89 # This root package name is expected to be found as a directory in
90 # some paths of the sys.path variable, especially the paths
91 # <MODULE_ROOT_DIR>/lib/pythonX.Y/site-packages/salome where are
92 # installed the python files. These paths are theorically appended by
93 # the SALOME main runner and should be in the sys.path at this point
94 # of the application. The extend_path is looking then for directories
95 # of the type:
96 #
97 # <MODULE_ROOT_DIR>/lib/pythonX.Y/site-packages/salome/<ROOT_PYTHONPACKAGE_NAME>
98 #
99 # And append them to the sys.path. These directories are supposed to
100 # be the pieces to be aggregated as a single virtual python package.
101 #
102 import os, sys
103 from salome_utils import verbose
104
105 MATCH_ENDING_PATTERN="site-packages" + os.path.sep + "salome"
106
107 def extend_path(pname):
108     for dir in sys.path:
109         if not isinstance(dir, str) or not os.path.isdir(dir) or not dir.endswith(MATCH_ENDING_PATTERN):
110             continue
111         subdir = os.path.join(dir, pname)
112         # XXX This may still add duplicate entries to path on
113         # case-insensitive filesystems
114         if os.path.isdir(subdir) and subdir not in __path__:
115             if verbose(): print("INFO - The directory %s is appended to sys.path" % subdir)
116             __path__.append(subdir)
117
118 extend_path(ROOT_PYTHONPACKAGE_NAME)
119 # ==========================================================================
120 #
121
122 from salome_kernel import *
123 from salome_study import *
124 from salome_iapp import *
125 import salome_study
126
127 #
128 # The next block is workaround for the problem of shared symbols loading for the extension modules (e.g. SWIG-generated)
129 # that causes RTTI unavailable in some cases. To solve this problem, sys.setdlopenflags() function is used.
130 # Depending on the Python version and platform, the dlopen flags can be defined in the dl, DLFUN or ctypes module.
131
132 import sys
133 flags = None
134 if not flags:
135     try:
136         # dl module can be unavailable
137         import dl
138         flags = dl.RTLD_NOW | dl.RTLD_GLOBAL
139     except Exception:
140         pass
141     pass
142 if not flags:
143     try:
144         # DLFCN module can be unavailable
145         import DLFCN
146         flags = DLFCN.RTLD_NOW | DLFCN.RTLD_GLOBAL
147     except Exception:
148         pass
149     pass
150 if not flags:
151     try:
152         # ctypes module can be unavailable
153         import ctypes
154         flags = ctypes.RTLD_GLOBAL
155     except Exception:
156         pass
157     pass
158
159 # Disable -> bug with scipy, seems very dangerous to do that
160 #if flags:
161 #    sys.setdlopenflags(flags)
162 #    pass
163
164 orb, lcc, naming_service, cm, sg, esm, dsm, modulcat = None,None,None,None,None,None,None,None
165 myStudy, myStudyName = None,None
166
167 salome_initial=True
168
169 def standalone():
170     pass
171
172 def withServers():
173     import KernelBasis
174     KernelBasis.setSSLMode(False)
175
176 def salome_init(path=None, embedded=False, iorfakensfile=None):
177     """
178     Initialize SALOME client process (that can also be server).
179     3 modes of initialization exists:
180     - SSL mode (see salome_init_without_session)
181     - SSL mode attached in the context of python execution inside SALOME_Container_No_NS_Serv server (typically YACS)
182     - Classical mode (see salome_init_with_session)
183     :param iorfakensfile: filename inside which IOR of fake NS will be written
184     """
185     if lcc is not None:
186         return
187     PATH_TO_STUDY_FILE_TO_INITIATE = "PATH_TO_STUDY_FILE_TO_INITIATE"
188     import KernelBasis
189     if KernelBasis.getSSLMode():
190         if KernelBasis.getIOROfEmbeddedNS() == "":
191             import os
192             # make runSalome.py -t study.hdf toto.py
193             if path is None and PATH_TO_STUDY_FILE_TO_INITIATE in os.environ:
194                 path = os.environ[PATH_TO_STUDY_FILE_TO_INITIATE]
195             salome_init_without_session(path, embedded, iorfakensfile)
196         else:
197             salome_init_without_session_attached(path, embedded)
198     else:
199         salome_init_with_session(path, embedded)
200
201 def salome_init_without_session_common(path=None, embedded=False):
202     from ORBConfigFile import writeORBConfigFileSSL
203     OMNIORB_USER_PATH = "OMNIORB_USER_PATH"
204     def RemoveOmniorbConfigFile():
205         import os
206         if "OMNIORB_CONFIG" in os.environ:
207             fileToRemove = os.environ["OMNIORB_CONFIG"]
208             if os.path.exists(fileToRemove):
209                 os.unlink(fileToRemove)
210
211     if OMNIORB_USER_PATH in os.environ:
212         import atexit
213         writeORBConfigFileSSL(os.environ[OMNIORB_USER_PATH],kwargs={"with_pid":True})
214         atexit.register(RemoveOmniorbConfigFile)
215
216     global lcc,naming_service,myStudy,orb,modulcat,sg
217     import KernelBasis
218     KernelBasis.setSSLMode(True)
219     import KernelDS
220     myStudy = KernelDS.myStudy()
221     import CORBA
222     orb=CORBA.ORB_init([''])
223     import KernelModuleCatalog
224     import SALOME_ModuleCatalog
225     from salome_kernel import list_of_catalogs_regarding_environement
226     modulcat = KernelModuleCatalog.myModuleCatalog( list_of_catalogs_regarding_environement() )
227     #
228     poa = orb.resolve_initial_references("RootPOA")
229     poaManager = poa._get_the_POAManager()
230     poaManager.activate()
231     #
232     sg = salome_iapp_init(embedded)
233     salome_study_init_without_session(path)
234     #
235     from NamingService import NamingService
236     naming_service = NamingService()
237
238 def salome_init_without_session(path=None, embedded=False, iorfakensfile=None):
239     """
240     Force creation of all servants needed by SALOME session in the current process.
241     A Fake NamingService is created storing reference of all servants in the current process.
242     """
243     salome_init_without_session_common(path,embedded)
244     global lcc,cm,dsm,esm
245     import KernelLauncher
246     cm = KernelLauncher.myContainerManager()
247     from LifeCycleCORBA import LifeCycleCORBASSL
248     lcc = LifeCycleCORBASSL()
249     # create a FactoryServer Container servant
250     import KernelContainer
251     KernelContainer.myContainer()
252     # activate poaManager to accept co-localized CORBA calls.
253     from KernelSDS import GetDSMInstance
254     import sys
255     if hasattr(sys, 'argv'):
256       argv = sys.argv
257     else:
258       argv = ['']
259     dsm = GetDSMInstance(argv)
260     # esm inherits from SALOME_CPythonHelper singleton already initialized by GetDSMInstance
261     # esm inherits also from SALOME_ResourcesManager creation/initialization (concerning SingleThreadPOA POA) when KernelLauncher.GetContainerManager() has been called
262     esm = KernelLauncher.GetExternalServer()
263     #
264     import KernelLogger
265     naming_service.Register(KernelLogger.myLogger(),"/Logger")
266     #
267     from NamingService import NamingService
268     if iorfakensfile is not None:
269         with open(iorfakensfile,"w") as iorfakensf:
270             iorfakensf.write(NamingService.IOROfNS())
271     
272 def salome_init_without_session_attached(path=None, embedded=False):
273     """
274     Configuration SSL inside a python interpretor launched in the SALOME_Container_No_NS_Serv.
275     In this configuration, a local FakeNamingService is created and remote objects are stored in it.
276     lcc is pointing to the FakeNamingService above.
277     """
278     salome_init_without_session_common(path,embedded)
279     global lcc,cm,dsm,esm
280     import CORBA
281     orb=CORBA.ORB_init([''])
282     import Engines
283     import KernelBasis
284     nsAbroad = orb.string_to_object( KernelBasis.getIOROfEmbeddedNS() )
285     import SALOME
286     CM_NAME_IN_NS = "/ContainerManager"
287     cm = orb.string_to_object( nsAbroad.Resolve(CM_NAME_IN_NS).decode() )
288     naming_service.Register(cm,CM_NAME_IN_NS)
289     RM_NAME_IN_NS = "/ResourcesManager"
290     rm = orb.string_to_object( nsAbroad.Resolve(RM_NAME_IN_NS).decode() )
291     naming_service.Register(rm,RM_NAME_IN_NS)
292     #
293     from LifeCycleCORBA import LifeCycleCORBASSL
294     lcc = LifeCycleCORBASSL()
295     DSM_NAME_IN_NS = "/DataServerManager"
296     dsm = orb.string_to_object( nsAbroad.Resolve(DSM_NAME_IN_NS).decode() )
297     naming_service.Register(dsm,DSM_NAME_IN_NS)
298     #
299     ESM_NAME_IN_NS = "/ExternalServers"
300     esm = orb.string_to_object( nsAbroad.Resolve(ESM_NAME_IN_NS).decode() )
301     naming_service.Register(esm,ESM_NAME_IN_NS)
302
303 def salome_init_with_session(path=None, embedded=False):
304     """
305     Performs only once SALOME general purpose initialisation for scripts.
306     Provides:
307     orb             reference to CORBA
308     lcc             a LifeCycleCorba instance
309     naming_service  a naming service instance
310     cm              reference to the container manager
311     esm             reference to external server manager
312     dsm             reference to shared dataserver manager
313     modulcat        reference to modulecatalog instance
314     sg              access to SALOME GUI (when linked with IAPP GUI)
315     myStudy         active study itself (CORBA reference)
316     myStudyName     active study name
317     """
318     global salome_initial
319     global orb, lcc, naming_service, cm, esm, dsm, modulcat
320     global sg
321     global myStudy, myStudyName
322     import KernelBasis
323     KernelBasis.setSSLMode(False)
324     try:
325         if salome_initial:
326             salome_initial=False
327             sg = salome_iapp_init(embedded)
328             orb, lcc, naming_service, cm, esm, dsm, modulcat = salome_kernel_init()
329             myStudy, myStudyName = salome_study_init(path)
330             pass
331         pass
332     except RuntimeError as inst:
333         # wait a little to avoid trace mix
334         import time
335         time.sleep(0.2)
336         x = inst
337         print("salome.salome_init_with_session():", x)
338         print("""
339         ============================================
340         May be there is no running SALOME session
341         salome.salome_init() is intended to be used
342         within an already running session
343         ============================================
344         """)
345         raise
346     
347 def salome_close():
348     global salome_initial, myStudy, myStudyName
349     try:
350         # study can be clear either from GUI or directly with salome.myStudy.Clear()
351         myStudy.Clear()
352     except Exception:
353         pass
354     salome_initial=True
355     salome_iapp_close()
356     salome_study_close()
357     myStudy, myStudyName = None, None
358     import KernelBasis
359     if KernelBasis.getSSLMode() and not KernelBasis.getGUIMode():
360         import KernelDS
361         KernelDS.KillGlobalSessionInstance()
362         import KernelSDS
363         KernelSDS.KillCPythonHelper()
364     pass
365
366 def salome_NS():
367     import CORBA
368     import CosNaming
369     orb = CORBA.ORB_init()
370     ns0 = orb.resolve_initial_references("NameService")
371     return ns0._narrow(CosNaming.NamingContext)
372
373 def salome_walk_on_containers(ns,root):
374     import CosNaming
375     it = ns.list(0)[1]
376     if not it:
377         return
378     cont = True
379     while cont:
380         cont,obj = it.next_one()
381         if cont:
382             if obj.binding_name[0].kind == "object":
383                 import Engines
384                 corbaObj = ns.resolve(obj.binding_name)
385                 if isinstance(corbaObj,Engines._objref_Container):
386                     yield corbaObj,(root,obj.binding_name[0].id)
387             else:
388                 father = ns.resolve([obj.binding_name[0]])
389                 for elt,elt2 in salome_walk_on_containers(father,root+[obj.binding_name[0].id]):
390                     yield elt,elt2
391             pass
392         pass
393     pass
394
395 def salome_shutdown_containers_with_session():
396     salome_init()
397     ns=salome_NS()
398     li = [elt for elt in salome_walk_on_containers(ns,[""])]
399     print("Number of containers in NS : {}".format(len(li)))
400     for cont,(root,cont_name) in li:
401         try:
402             cont.Shutdown()
403         except Exception:
404             pass
405         ref_in_ns = "/".join(root+[cont_name])
406         naming_service.Destroy_Name(ref_in_ns)
407     print("Number of containers in NS after clean : {}".format( len( list(salome_walk_on_containers(ns,[""])) )))
408     
409 def salome_shutdown_containers_without_session():
410     containersEntries = [elt for elt in naming_service.repr() if "/Containers/" == elt[:12]]
411     for containerEntry in containersEntries:
412         cont = naming_service.Resolve(containerEntry)
413         try:
414             cont.Shutdown()
415         except:
416             pass
417
418 def salome_shutdown_containers():
419     import KernelBasis
420     if KernelBasis.getSSLMode():
421         salome_shutdown_containers_without_session()
422     else:
423         salome_shutdown_containers_with_session()
424
425 class SessionContextManager:
426     def __enter__(self):
427         standalone()
428         salome_init()
429     def __exit__(self, type, value, traceback):
430         salome_close()
431
432 #to expose all objects to pydoc
433 __all__=dir()