Package omero :: Module clients
[hide private]
[frames] | no frames]

Source Code for Module omero.clients

  1  #!/usr/bin/env python 
  2  """ 
  3   
  4     Copyright 2009 Glencoe Software, Inc. All rights reserved. 
  5     Use is subject to license terms supplied in LICENSE.txt 
  6   
  7  """ 
  8   
  9  __save__ = __name__ 
 10  __name__ = 'omero' 
 11  try: 
 12      api = __import__('omero.api') 
 13      model = __import__('omero.model') 
 14      util = __import__('omero.util') 
 15      sys = __import__('omero.sys') 
 16      import omero.all 
 17  finally: 
 18      __name__ = __save__ 
 19      del __save__ 
 20   
 21  sys = __import__("sys") 
 22  import exceptions, traceback, threading, logging 
 23  import Ice, Glacier2, Glacier2_Router_ice 
 24  import uuid 
 25   
26 -class BaseClient(object):
27 """ 28 Central client-side blitz entry point, and should be in sync with OmeroJava's omero.client 29 and OmeroCpp's omero::client. 30 31 Typical usage includes:: 32 33 client = omero.client() # Uses --Ice.Config argument or ICE_CONFIG variable 34 client = omero.client(host = host) # Defines "omero.host" 35 client = omero.client(host = host, port = port) # Defines "omero.host" and "omero.port" 36 37 For more information, see: 38 39 - U{https://trac.openmicroscopy.org.uk/omero/wiki/ClientDesign} 40 41 """ 42
43 - def __init__(self, args = None, id = None, \ 44 host = None, port = None, pmap = None):
45 """ 46 Constructor which takes one sys.argv-style list, one initialization 47 data, one host string, one port integer, and one properties map, in 48 that order. *However*, to simplify use, we reassign values based on 49 their type with a warning printed. A cleaner approach is to use named 50 parameters. 51 :: 52 c1 = omero.client(None, None, "host", myPort) # Correct 53 c2 = omero.client(host = "host", port = myPort) # Correct 54 c3 = omero.client("host", myPort) # Works with warning 55 56 Both "Ice" and "omero" prefixed properties will be parsed. 57 58 Defines the state variables:: 59 __previous : InitializationData from any previous communicator, if any 60 Used to re-initialization the client post-closeSession() 61 62 __ic : communicator. Nullness => init() needed on createSession() 63 64 __sf : current session. Nullness => createSession() needed. 65 66 __resources: if non-null, hs access to this client instance and will 67 periodically call sf.keepAlive(None) in order to keep any 68 session alive. This can be enabled either via the omero.keep_alive 69 configuration property, or by calling the enableKeepAlive() method. 70 Once enabled, the period cannot be adjusted during a single 71 session. 72 73 Modifying these variables outside of the accessors can lead to 74 undefined behavior. 75 76 Equivalent to all OmeroJava and OmeroCpp constructors 77 """ 78 79 # Setting all protected values to prevent AttributeError 80 self.__agent = "OMERO.py" #: See setAgent 81 self.__insecure = False 82 self.__previous = None 83 self.__ic = None 84 self.__oa = None 85 self.__sf = None 86 self.__uuid = None 87 self.__resources = None 88 self.__lock = threading.RLock() 89 90 # Logging 91 self.__logger = logging.getLogger("omero.client") 92 logging.basicConfig() # Does nothing if already configured 93 94 # Reassigning based on argument type 95 96 args, id, host, port, pmap = self._repair(args, id, host, port, pmap) 97 98 # Copying args since we don't really want them edited 99 if not args: 100 args = [] 101 else: 102 args = list(args) 103 104 # Equiv to multiple constructors. ####################### 105 if id == None: 106 id = Ice.InitializationData() 107 108 if id.properties == None: 109 id.properties = Ice.createProperties(args) 110 111 id.properties.parseCommandLineOptions("omero", args); 112 if host: 113 id.properties.setProperty("omero.host", str(host)) 114 if not port: 115 port = id.properties.getPropertyWithDefault("omero.port",\ 116 str(omero.constants.GLACIER2PORT)) 117 id.properties.setProperty("omero.port", str(port)) 118 if pmap: 119 for k,v in pmap.items(): 120 id.properties.setProperty(str(k), str(v)) 121 122 self._initData(id)
123
124 - def _repair(self, args, id, host, port, pmap):
125 """ 126 Takes the 5 arguments passed to the __init__ method 127 and attempts to re-order them based on their types. 128 This allows for simplified usage without parameter 129 names. 130 """ 131 types = [list, Ice.InitializationData, str, int, dict] 132 original = [args, id, host, port, pmap] 133 repaired = [None, None, None, None, None] 134 135 # Check all to see if valid 136 valid = True 137 for i in range(0, len(types)): 138 if None != original[i] and not isinstance(original[i], types[i]): 139 valid = False 140 break 141 if valid: 142 return original 143 144 # Now try to find corrections. 145 for i in range(0, len(types)): 146 found = None 147 for j in range(0, len(types)): 148 if isinstance(original[j], types[i]): 149 if not found: 150 found = original[j] 151 else: 152 raise omero.ClientError("Found two arguments of same type: " + str(types[i])) 153 if found: 154 repaired[i] = found 155 return repaired
156
157 - def _initData(self, id):
158 """ 159 Initializes the current client via an Ice.InitializationData 160 instance. This is called by all of the constructors, but may 161 also be called on createSession(name, pass) if a previous 162 call to closeSession() has nulled the Ice.Communicator. 163 """ 164 165 if not id: 166 raise ClientError("No initialization data provided."); 167 168 # Strictly necessary for this class to work 169 id.properties.setProperty("Ice.ImplicitContext", "Shared") 170 id.properties.setProperty("Ice.ACM.Client", "0") 171 id.properties.setProperty("Ice.RetryIntervals", "-1") 172 id.properties.setProperty("Ice.Default.EndpointSelection", "Ordered") 173 id.properties.setProperty("Ice.Default.PreferSecure", "1") 174 id.properties.setProperty("Ice.Plugin.IceSSL" , "IceSSL:createIceSSL") 175 id.properties.setProperty("IceSSL.Ciphers" , "ADH") 176 id.properties.setProperty("IceSSL.VerifyPeer" , "0") 177 178 # Setting MessageSizeMax 179 messageSize = id.properties.getProperty("Ice.MessageSizeMax") 180 if not messageSize or len(messageSize) == 0: 181 id.properties.setProperty("Ice.MessageSizeMax", str(omero.constants.MESSAGESIZEMAX)) 182 183 # Setting ConnectTimeout 184 self.parseAndSetInt(id, "Ice.Override.ConnectTimeout",\ 185 omero.constants.CONNECTTIMEOUT) 186 187 # Endpoints set to tcp if not present 188 endpoints = id.properties.getProperty("omero.ClientCallback.Endpoints") 189 if not endpoints or len(endpoints) == 0: 190 id.properties.setProperty("omero.ClientCallback.Endpoints", "tcp") 191 192 # ThreadPool to 5 if not present 193 threadpool = id.properties.getProperty("omero.ClientCallback.ThreadPool.Size") 194 if not threadpool or len(threadpool) == 0: 195 id.properties.setProperty("omero.ClientCallback.ThreadPool.Size", str(omero.constants.CLIENTTHREADPOOLSIZE)) 196 197 # Port, setting to default if not present 198 port = self.parseAndSetInt(id, "omero.port",\ 199 omero.constants.GLACIER2PORT) 200 201 # Default Router, set a default and then replace 202 router = id.properties.getProperty("Ice.Default.Router") 203 if not router or len(router) == 0: 204 router = str(omero.constants.DEFAULTROUTER) 205 host = id.properties.getPropertyWithDefault("omero.host", """<"omero.host" not set>""") 206 router = router.replace("@omero.port@", str(port)) 207 router = router.replace("@omero.host@", str(host)) 208 id.properties.setProperty("Ice.Default.Router", router) 209 210 # Dump properties 211 dump = id.properties.getProperty("omero.dump") 212 if len(dump) > 0: 213 m = self.getPropertyMap(id.properties) 214 keys = list(m.keys()) 215 keys.sort() 216 for key in keys: 217 print "%s=%s" % (key, m[key]) 218 219 self.__lock.acquire() 220 try: 221 if self.__ic: 222 raise ClientError("Client already initialized") 223 224 self.__ic = Ice.initialize(id) 225 226 if not self.__ic: 227 raise ClientError("Improper initialization") 228 229 # Register Object Factory 230 self.of = ObjectFactory() 231 self.of.registerObjectFactory(self.__ic) 232 for of in omero.rtypes.ObjectFactories.values(): 233 of.register(self.__ic) 234 235 # Define our unique identifier (used during close/detach) 236 self.__uuid = str(uuid.uuid4()) 237 ctx = self.__ic.getImplicitContext() 238 if not ctx: 239 raise ClientError("Ice.ImplicitContext not set to Shared") 240 ctx.put(omero.constants.CLIENTUUID, self.__uuid) 241 242 # Register the default client callback 243 self.__oa = self.__ic.createObjectAdapter("omero.ClientCallback") 244 cb = BaseClient.CallbackI(self.__ic, self.__oa) 245 self.__oa.add(cb, self.__ic.stringToIdentity("ClientCallback/%s" % self.__uuid)) 246 self.__oa.activate() 247 finally: 248 self.__lock.release()
249
250 - def setAgent(self, agent):
251 """ 252 Sets the omero.model.Session#getUserAgent() string for 253 this client. Every session creation will be passed this argument. Finding 254 open sesssions with the same agent can be done via 255 omero.api.ISessionPrx#getMyOpenAgentSessions(String). 256 """ 257 self.__agent = agent
258
259 - def isSecure(self):
260 """ 261 Specifies whether or not this client was created via a call to 262 createClient with a boolean of False. If insecure, then all 263 remote calls will use the insecure connection defined by the server. 264 """ 265 return not self.__insecure
266
267 - def createClient(self, secure):
268 """ 269 Creates a possibly insecure omero.client instance and calls joinSession 270 using the current getSessionId value. If secure is False, then first the 271 "omero.router.insecure" configuration property is retrieved from the server 272 and used as the value of "Ice.Default.Router" for the new client. Any exception 273 thrown during creation is passed on to the caller. 274 """ 275 props = self.getPropertyMap() 276 if not secure: 277 insecure = self.getSession().getConfigService().getConfigValue("omero.router.insecure") 278 if insecure is not None and insecure != "": 279 props["Ice.Default.Router"] = insecure 280 else: 281 self.__logger.warn("Could not retrieve \"omero.router.insecure\"") 282 283 nClient = omero.client(props) 284 nClient.__insecure = not secure 285 nClient.setAgent("%s;secure=%s" % (self.__agent, secure)) 286 nClient.joinSession(self.getSessionId()) 287 return nClient
288
289 - def __del__(self):
290 """ 291 Calls closeSession() and ignores any exceptions. 292 293 Equivalent to close() in OmeroJava or omero::client::~client() 294 """ 295 try: 296 self.closeSession() 297 except exceptions.Exception, e: 298 self.__logger.warning("Ignoring error in client.__del__:" + str(e.__class__))
299
300 - def getCommunicator(self):
301 """ 302 Returns the Ice.Communicator for this instance or throws 303 an exception if None. 304 """ 305 self.__lock.acquire() 306 try: 307 if not self.__ic: 308 raise ClientError("No Ice.Communicator active; call createSession() or create a new client instance") 309 return self.__ic 310 finally: 311 self.__lock.release()
312
313 - def getAdapter(self):
314 """ 315 Returns the Ice.ObjectAdapter for this instance or throws 316 an exception if None. 317 """ 318 self.__lock.acquire() 319 try: 320 if not self.__oa: 321 raise ClientError("No Ice.ObjectAdapter active; call createSession() or create a new client instance") 322 return self.__oa 323 finally: 324 self.__lock.release()
325
326 - def getSession(self):
327 """ 328 Returns the current active session or throws an exception if none has been 329 created since the last closeSession() 330 """ 331 self.__lock.acquire() 332 try: 333 sf = self.__sf 334 if not sf: 335 raise omero.ClientError("No session avaliable") 336 return sf 337 finally: 338 self.__lock.release()
339
340 - def getSessionId(self):
341 """ 342 Returns the UUID for the current session without making a remote call. 343 Uses getSession() internally and will throw an exception if no session 344 is active. 345 """ 346 return self.getSession().ice_getIdentity().name
347
348 - def getImplicitContext(self):
349 """ 350 Returns the Ice.ImplicitContext which defines what properties 351 will be sent on every method invocation. 352 """ 353 return self.getCommunicator().getImplicitContext()
354
355 - def getProperties(self):
356 """ 357 Returns the active properties for this instance 358 """ 359 self.__lock.acquire() 360 try: 361 return self.__ic.getProperties() 362 finally: 363 self.__lock.release()
364
365 - def getProperty(self, key):
366 """ 367 Returns the property for the given key or "" if none present 368 """ 369 return self.getProperties().getProperty(key)
370
371 - def getPropertyMap(self, properties = None):
372 """ 373 Returns all properties which are prefixed with "omero." or "Ice." 374 """ 375 if properties is None: 376 properties = self.getProperties() 377 378 rv = dict() 379 for prefix in ["omero","Ice"]: 380 for k,v in properties.getPropertiesForPrefix(prefix).items(): 381 rv[k] = v 382 return rv
383
384 - def joinSession(self, session):
385 """ 386 Uses the given session uuid as name 387 and password to rejoin a running session 388 """ 389 return self.createSession(session, session)
390
391 - def createSession(self, username=None, password=None):
392 """ 393 Performs the actual logic of logging in, which is done via the 394 getRouter(). Disallows an extant ServiceFactoryPrx, and 395 tries to re-create a null Ice.Communicator. A null or empty 396 username will throw an exception, but an empty password is allowed. 397 """ 398 import omero 399 400 self.__lock.acquire() 401 try: 402 403 # Checking state 404 405 if self.__sf: 406 raise ClientError("Session already active. Create a new omero.client or closeSession()") 407 408 if not self.__ic: 409 if not self.__previous: 410 raise ClientError("No previous data to recreate communicator.") 411 self._initData(self.__previous) 412 self.__previous = None 413 414 # Check the required properties 415 416 if not username: 417 username = self.getProperty("omero.user") 418 elif isinstance(username,omero.RString): 419 username = username.val 420 421 if not username or len(username) == 0: 422 raise ClientError("No username specified") 423 424 if not password: 425 password = self.getProperty("omero.pass") 426 elif isinstance(password,omero.RString): 427 password = password.val 428 429 if not password: 430 raise ClientError("No password specified") 431 432 # Acquire router and get the proxy 433 prx = None 434 retries = 0 435 while retries < 3: 436 reason = None 437 if retries > 0: 438 self.__logger.warning(\ 439 "%s - createSession retry: %s"% (reason, retries) ) 440 try: 441 ctx = dict(self.getImplicitContext().getContext()) 442 ctx[omero.constants.AGENT] = self.__agent 443 prx = self.getRouter(self.__ic).createSession(username, password, ctx) 444 break 445 except omero.WrappedCreateSessionException, wrapped: 446 if not wrapped.concurrency: 447 raise wrapped # We only retry concurrency issues. 448 reason = "%s:%s" % (wrapped.type, wrapped.reason) 449 retries = retries + 1 450 except Ice.ConnectTimeoutException, cte: 451 reason = "Ice.ConnectTimeoutException:%s" % str(cte) 452 retries = retries + 1 453 454 if not prx: 455 raise ClientError("Obtained null object prox") 456 457 # Check type 458 self.__sf = omero.api.ServiceFactoryPrx.uncheckedCast(prx) 459 if not self.__sf: 460 raise ClientError("Obtained object proxy is not a ServiceFactory") 461 462 # Configure keep alive 463 keep_alive = self.__ic.getProperties().getPropertyWithDefault("omero.keep_alive", "-1") 464 try: 465 i = int(keep_alive) 466 self.enableKeepAlive(i) 467 except: 468 pass 469 470 # Set the client callback on the session 471 # and pass it to icestorm 472 try: 473 id = self.__ic.stringToIdentity("ClientCallback/%s" % self.__uuid ) 474 raw = self.__oa.createProxy(id) 475 self.__sf.setCallback(omero.api.ClientCallbackPrx.uncheckedCast(raw)) 476 #self.__sf.subscribe("/public/HeartBeat", raw) 477 except: 478 self.__del__() 479 raise 480 481 # Set the session uuid in the implicit context 482 self.getImplicitContext().put(omero.constants.SESSIONUUID, self.getSessionId()) 483 484 return self.__sf 485 finally: 486 self.__lock.release()
487
488 - def enableKeepAlive(self, seconds):
489 """ 490 Resets the "omero.keep_alive" property on the current 491 Ice.Communicator which is used on initialization to determine 492 the time-period between Resource checks. If no __resources 493 instance is available currently, one is also created. 494 """ 495 496 self.__lock.acquire() 497 try: 498 # A communicator must be configured! 499 ic = self.getCommunicator() 500 # Setting this here guarantees that after closeSession() 501 # the next createSession() will use the new value despite 502 # what was in the configuration file 503 ic.getProperties().setProperty("omero.keep_alive", str(seconds)) 504 505 # If it's not null, then there's already an entry for keeping 506 # any existing session alive 507 if self.__resources == None and seconds > 0: 508 self.__resources = omero.util.Resources(seconds) 509 class Entry: 510 def __init__(self, c): 511 self.c = c
512 def cleanup(self): pass 513 def check(self): 514 sf = self.c._BaseClient__sf 515 ic = self.c._BaseClient__ic 516 if sf != None: 517 try: 518 sf.keepAlive(None) 519 except exceptions.Exception, e: 520 if ic != None: 521 ic.getLogger().warning("Proxy keep alive failed.") 522 return False 523 return True
524 self.__resources.add(Entry(self)) 525 finally: 526 self.__lock.release() 527
528 - def getRouter(self, comm):
529 """ 530 Acquires the default router, and throws an exception 531 if it is not of type Glacier2.Router. Also sets the 532 Ice.ImplicitContext on the router proxy. 533 """ 534 prx = comm.getDefaultRouter() 535 if not prx: 536 raise ClientError("No default router found.") 537 router = Glacier2.RouterPrx.uncheckedCast(prx) 538 if not router: 539 raise ClientError("Error obtaining Glacier2 router") 540 541 # For whatever reason, we have to set the context 542 # on the router context here as well 543 router = router.ice_context(comm.getImplicitContext().getContext()) 544 return router
545
546 - def sha1(self, filename):
547 """ 548 Calculates the local sha1 for a file. 549 """ 550 try: 551 from hashlib import sha1 as sha_new 552 except ImportError: 553 from sha import new as sha_new 554 digest = sha_new() 555 file = open(filename, 'rb') 556 try: 557 while True: 558 block = file.read(1024) 559 if not block: 560 break 561 digest.update(block) 562 finally: 563 file.close() 564 return digest.hexdigest()
565
566 - def upload(self, filename, name = None, path = None, 567 type = None, ofile = None, block_size = 1024):
568 """ 569 Utility method to upload a file to the server. 570 """ 571 if not self.__sf: 572 raise ClientError("No session. Use createSession first.") 573 574 import os, types 575 if not filename or not isinstance(filename, types.StringType): 576 raise ClientError("Non-null filename must be provided") 577 578 if not os.path.exists(filename): 579 raise ClientError("File does not exist: " + filename) 580 581 from path import path as __path__ 582 filepath = __path__(filename) 583 file = open(filename, 'rb') 584 try: 585 586 size = os.path.getsize(file.name) 587 if block_size > size: 588 block_size = size 589 590 if not ofile: 591 ofile = omero.model.OriginalFileI() 592 593 ofile.size = omero.rtypes.rlong(size) 594 ofile.sha1 = omero.rtypes.rstring(self.sha1(file.name)) 595 596 abspath = filepath.normpath().abspath() 597 if not ofile.name: 598 if name: 599 ofile.name = omero.rtypes.rstring(name) 600 else: 601 ofile.name = omero.rtypes.rstring(str(abspath.basename())) 602 603 if not ofile.path: 604 ofile.path = omero.rtypes.rstring(str(abspath.dirname())+os.path.sep) 605 606 if not ofile.mimetype: 607 if type: 608 # ofile.mimetype = 'application/octet-stream' by default 609 ofile.mimetype = omero.rtypes.rstring(type) 610 611 # Disabled with group permissions #1434 612 # if permissions: 613 # ofile.details.permissions = permissions 614 615 up = self.__sf.getUpdateService() 616 ofile = up.saveAndReturnObject(ofile) 617 618 prx = self.__sf.createRawFileStore() 619 try: 620 prx.setFileId(ofile.id.val) 621 prx.truncate(size) # ticket:2337 622 offset = 0 623 while True: 624 block = file.read(block_size) 625 if not block: 626 break 627 prx.write(block, offset, len(block)) 628 offset += len(block) 629 finally: 630 prx.close() 631 finally: 632 file.close() 633 634 return ofile
635
636 - def download(self, ofile, filename = None, block_size = 1024*1024, filehandle = None):
637 prx = self.__sf.createRawFileStore() 638 try: 639 if not ofile or not ofile.id: 640 raise ClientError("No file to download") 641 ofile = self.__sf.getQueryService().get("OriginalFile", ofile.id.val) 642 643 if block_size > ofile.size.val: 644 block_size = ofile.size.val 645 646 prx.setFileId(ofile.id.val) 647 648 size = ofile.size.val 649 offset = 0 650 651 if filehandle is None: 652 if filename is None: 653 raise ClientError("no filename or filehandle specified") 654 filehandle = open(filename, 'wb') 655 else: 656 if filename: 657 raise ClientError("filename and filehandle specified.") 658 659 try: 660 while (offset+block_size) < size: 661 filehandle.write(prx.read(offset, block_size)) 662 offset += block_size 663 filehandle.write(prx.read(offset, (size-offset))) 664 finally: 665 filehandle.close() 666 finally: 667 prx.close()
668
669 - def closeSession(self):
670 """ 671 Closes the Router connection created by createSession(). Due to a bug in Ice, 672 only one connection is allowed per communicator, so we also destroy the communicator. 673 """ 674 675 self.__lock.acquire() 676 try: 677 self.__sf = None 678 679 oldOa = self.__oa 680 self.__oa = None 681 682 oldIc = self.__ic 683 self.__ic = None 684 685 # Only possible if improperly configured. 686 if not oldIc: 687 return 688 689 if oldOa: 690 try: 691 oldOa.deactivate() 692 except exceptions.Exception, e: 693 self.__logger.warning("While deactivating adapter: " + str(e.message)) 694 695 self.__previous = Ice.InitializationData() 696 self.__previous.properties = oldIc.getProperties().clone() 697 698 oldR = self.__resources 699 self.__resources = None 700 if oldR != None: 701 try: 702 oldR.cleanup() 703 except exceptions.Exception, e: 704 oldIc.getLogger().warning( 705 "While cleaning up resources: " + str(e)) 706 707 try: 708 try: 709 self.getRouter(oldIc).destroySession() 710 except Glacier2.SessionNotExistException: 711 # ok. We don't want it to exist 712 pass 713 except Ice.ConnectionLostException: 714 # ok. Exception will always be thrown 715 pass 716 except Ice.ConnectionRefusedException: 717 # ok. Server probably went down 718 pass 719 except Ice.ConnectTimeoutException: 720 # ok. Server probably went down 721 pass 722 # Possible other items to handle/ignore: 723 # * Ice.DNSException 724 finally: 725 oldIc.destroy() 726 del oldIc._impl # WORKAROUND ticket:2007 727 728 finally: 729 self.__lock.release()
730 731
732 - def killSession(self):
733 """ 734 Calls ISession.closeSession(omero.model.Session) until 735 the returned reference count is greater than zero. The 736 number of invocations is returned. If ISession.closeSession() 737 cannot be called, -1 is returned. 738 """ 739 740 s = omero.model.SessionI() 741 s.uuid = omero.rtypes.rstring(self.getSessionId()) 742 try: 743 svc = self.sf.getSessionService() 744 except: 745 self.__logger.warning("Cannot get session service for killSession. Using closeSession") 746 self.closeSession() 747 return -1; 748 749 count = 0 750 try: 751 r = 1 752 while r > 0: 753 count += 1 754 r = svc.closeSession(s) 755 except omero.RemovedSessionException: 756 pass 757 except: 758 self.__logger.warning("Unknown exception while closing all references", exc_info = True) 759 760 # Now the server-side session is dead, call closeSession() 761 self.closeSession() 762 return count
763 764 # Environment Methods 765 # =========================================================== 766
767 - def _env(self, _unwrap, method, *args):
768 """ Helper method to access session environment""" 769 session = self.getSession() 770 if not session: 771 raise ClientError("No session active") 772 a = session.getAdminService() 773 u = a.getEventContext().sessionUuid 774 s = session.getSessionService() 775 m = getattr(s, method) 776 rv = apply(m, (u,)+args) 777 if callable(_unwrap): 778 rv = _unwrap(rv) # Passed in function 779 elif _unwrap: 780 rv = omero.rtypes.unwrap(rv) # Default method 781 return rv
782
783 - def getInput(self, key, unwrap=False):
784 """ 785 Retrieves an item from the "input" shared (session) memory. 786 """ 787 return self._env(unwrap, "getInput", key)
788
789 - def getOutput(self, key, unwrap=False):
790 """ 791 Retrieves an item from the "output" shared (session) memory. 792 """ 793 return self._env(unwrap, "getOutput", key)
794 795
796 - def setInput(self, key, value):
797 """ 798 Sets an item in the "input" shared (session) memory under the given name. 799 """ 800 self._env(False, "setInput", key, value)
801
802 - def setOutput(self, key, value):
803 """ 804 Sets an item in the "output" shared (session) memory under the given name. 805 """ 806 self._env(False, "setOutput", key, value)
807
808 - def getInputKeys(self):
809 """ 810 Returns a list of keys for all items in the "input" shared (session) memory 811 """ 812 return self._env(False, "getInputKeys")
813
814 - def getOutputKeys(self):
815 """ 816 Returns a list of keys for all items in the "output" shared (session) memory 817 """ 818 return self._env(False, "getOutputKeys")
819
820 - def getInputs(self, unwrap=False):
821 """ 822 Returns all items in the "input" shared (session) memory 823 """ 824 return self._env(unwrap, "getInputs")
825
826 - def getOutputs(self, unwrap=False):
827 """ 828 Returns all items in the "output" shared (session) memory 829 """ 830 return self._env(unwrap, "getOutputKeys")
831 # 832 # Misc. 833 # 834
835 - def parseAndSetInt(self, data, key, newValue):
836 currentValue = data.properties.getProperty(key) 837 if not currentValue or len(currentValue) == 0: 838 newStr = str(newValue) 839 data.properties.setProperty(key, newStr) 840 currentValue = newStr 841 return currentValue
842
843 - def __getattr__(self, name):
844 """ 845 Compatibility layer, which allows calls to getCommunicator() and getSession() 846 to be called via self.ic and self.sf 847 """ 848 if name == "ic": 849 return self.getCommunicator() 850 elif name == "sf": 851 return self.getSession() 852 elif name == "adapter": 853 return self.getAdapter() 854 else: 855 raise AttributeError("Unknown property: " + name)
856 857 # 858 # Callback 859 #
860 - def _getCb(self):
861 if not self.__oa: 862 raise ClientError("No session active; call createSession()") 863 obj = self.__oa.find(self.ic.stringToIdentity("ClientCallback/%s" % self.__uuid)) 864 if not isinstance(obj, BaseClient.CallbackI): 865 raise ClientError("Cannot find CallbackI in ObjectAdapter") 866 return obj
867
868 - def onHeartbeat(self, myCallable):
869 self._getCb().onHeartbeat = myCallable
870
871 - def onSessionClosed(self, myCallable):
872 self._getCb().onSessionClosed = myCallable
873
874 - def onShutdownIn(self, myCallable):
875 self._getCb().onShutdownIn = myCallable
876
877 - class CallbackI(omero.api.ClientCallback):
878 """ 879 Implemention of ClientCallback which will be added to 880 any Session which this instance creates. Note: this client 881 should avoid all interaction with the {@link client#lock} since it 882 can lead to deadlocks during shutdown. See: ticket:1210 883 """ 884 885 # 886 # Default callbacks 887 #
888 - def _noop(self):
889 pass
890 - def _closeSession(self):
891 try: 892 self.oa.deactivate(); 893 except exceptions.Exception, e: 894 sys.err.write("On session closed: " + str(e))
895
896 - def __init__(self, ic, oa):
897 self.ic = ic 898 self.oa = oa 899 self.onHeartbeat = self._noop 900 self.onShutdownIn = self._noop 901 self.onSessionClosed = self._noop
902 - def execute(self, myCallable, action):
903 try: 904 myCallable() 905 # self.ic.getLogger().trace("ClientCallback", action + " run") 906 except: 907 try: 908 self.ic.getLogger().error("Error performing %s" % action) 909 except: 910 print "Error performing %s" % action
911
912 - def requestHeartbeat(self, current = None):
913 self.execute(self.onHeartbeat, "heartbeat")
914 - def shutdownIn(self, milliseconds, current = None):
915 self.execute(self.onShutdownIn, "shutdown")
916 - def sessionClosed(self, current = None):
917 self.execute(self.onSessionClosed, "sessionClosed")
918 919 # 920 # Other 921 # 922 923 import util.FactoryMap
924 -class ObjectFactory(Ice.ObjectFactory):
925 """ 926 Responsible for instantiating objects during deserialization. 927 """ 928
929 - def __init__(self, pmap = util.FactoryMap.map()):
930 self.__m = pmap
931
932 - def registerObjectFactory(self, ic):
933 for key in self.__m: 934 if not ic.findObjectFactory(key): 935 ic.addObjectFactory(self,key)
936
937 - def create(self, type):
938 generator = self.__m[type] 939 if generator == None: 940 raise ClientError("Unknown type:"+type) 941 return generator.next()
942
943 - def destroy(self):
944 # Nothing to do 945 pass
946 947 948
949 -class ClientError(exceptions.Exception):
950 """ 951 Top of client exception hierarchy. 952 """ 953 pass
954
955 -class UnloadedEntityException(ClientError):
956 pass
957
958 -class UnloadedCollectionException(ClientError):
959 pass
960