From c5d8bf9e42de54d590b0c3bcdb5f822a1fecb4a2 Mon Sep 17 00:00:00 2001 From: Diane Adjavon <diane.adjavon@ed.ac.uk> Date: Fri, 7 Feb 2020 15:54:49 +0000 Subject: [PATCH] Begin testing suite --- README.md | 25 +++++++++++++-- config.json | 1 + core/__init__.py | 1 + core/{omero.py => connect.py} | 42 ++++++++++--------------- install.sh | 6 ++++ omero_py/__init__.py | 5 +++ test/__init__.py | 0 test/connect_to_omero.py | 54 ++++++++++++++++---------------- test/test_connections.py | 59 +++++++++++++++++++++++++++++++++++ 9 files changed, 138 insertions(+), 55 deletions(-) create mode 100644 config.json rename core/{omero.py => connect.py} (64%) create mode 100644 install.sh create mode 100644 omero_py/__init__.py create mode 100644 test/__init__.py create mode 100644 test/test_connections.py diff --git a/README.md b/README.md index 0f6d0e0d..73ab9ee6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,26 @@ The core classes and methods for the python microfluidics, microscopy, and analysis pypline pipeline. -References: -* OMERO python bindings : https://docs.openmicroscopy.org/omero/5.4.0/developers/Python.html -* Ice3.5 : https://zeroc.com/downloads/ice/3.5#macos +## References +* [OMERO python bindings](https://docs.openmicroscopy.org/omero/5.4.0/developers/Python.html) +* [Zeroc-ice python](https://pypi.org/project/zeroc-ice/3.6.5/) + +## Installation +How to set up access to OMERO from python: +* Install openssl headers version 1.0.2: `sudo apt-get install libssl1.0-dev` +* Install the corresponding openssl (as default is 1.1.1): `conda install openssl==1.0.2k` +* Install bzip headers : `sudo apt-get install libbz2-dev` +* Install zeroc-ice from PyPI, which includes Ice: `pip install zeroc-ice==3.6.0` +* Run `connect_to_omero.py` as a test (TODO TESTS) + +## Disclaimers +TLDR: Most of this stuff is depcrecated. +Using OMERO 5.2.5 means that we need to use depreacted python 2.7 (EOL 2020.01.01), +and we need to use `zeroc-ice` version 3.6 which is also dropped in the newer version of OMERO. +The local version of `openssl` (`conda`) needs to fit the headers of `libssl-dev` (`apt-get`). +By default conda will install OpenSSL version 1.1.1 as all the others are no longer maintained. +However, using the headers of verions 1.0.2 means that we have to downgrade OpenSSL to version 1.0.2 also. + +It is highly recommended that we upgrade OMERO to 5.6 in order to use Python 3, in which case it will even +be possible to get OMERO.py directly from PyPI with easy installation, [omero-py](https://pypi.org/project/omero-py/) diff --git a/config.json b/config.json new file mode 100644 index 00000000..2cadfef2 --- /dev/null +++ b/config.json @@ -0,0 +1 @@ +{"host": "sce-bio-c04287.bio.ed.ac.uk", "password": "***REMOVED***", "port": 4064, "user": "upload"} diff --git a/core/__init__.py b/core/__init__.py index e69de29b..d28ccbde 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -0,0 +1 @@ +import omero_py diff --git a/core/omero.py b/core/connect.py similarity index 64% rename from core/omero.py rename to core/connect.py index 1f148c3a..3389fcda 100644 --- a/core/omero.py +++ b/core/connect.py @@ -5,68 +5,56 @@ # Copyright (C) 2014 University of Dundee & Open Microscopy Environment. # All Rights Reserved. # Use is subject to license terms supplied in LICENSE.txt +import itertools - -USERNAME = 'upload' -PASSWORD = '***REMOVED***' -HOST = 'sce-bio-c04287.bio.ed.ac.uk' -PORT = 4064 from omero.gateway import BlitzGateway from utils import repr_obj class Database: - def __init__(self): - self.conn = BlitzGateway(USERNAME, PASSWORD, host=HOST, port=PORT) + def __init__(self, username, password, host, port): + self.conn = BlitzGateway(username, password, host=host, port=port) def __repr__(self): return repr_obj(self.conn) _ - def connect(self): + def connect(self, secure=False): connected = self.conn.connect() - - # Check if you are connected - # ========================== - if not connected: - import sys - sys.stderr.write( - "Error: Connection not available, please check your user name and" - " password.\n") - sys.exit(1) - - # Using secure connection - # ======================= - # By default, once we have logged in, data transfer is not encrypted - # (faster) - # To use a secure connection, call setSecure(True): - - #self.conn.setSecure(True) # <--------- Uncomment this + self.conn.setSecure(secure) + return connected def disconnect(self): self.conn.seppuku() @property def user(self): + # TODO cache user = self.conn.getUser() return dict(ID=user.getId(), Username=user.getName()) @property def groups(self): + # TODO cache return [dict(ID=g.getId(), Name=g.getName()) for g in self.conn.getGroupsMemberOf()] @property def current_group(self): + # TODO cache g = self.conn.getGroupFromContext() return dict(ID=g.getId(), Name=g.getName()) def isAdmin(self): + # TODO cache return self.conn.isAdmin() def getDataset(self, dataset_id): ds = self.conn.getObject("Dataset", dataset_id) return Dataset(ds) + def getDatasets(self, n): + top_n = itertools.islice(self.conn.getObjects("Dataset"), n) + return [Dataset(ds) for ds in top_n] class Dataset: def __init__(self, dataset_wrapper): @@ -75,6 +63,10 @@ class Dataset: def __repr__(self): return repr_obj(self.dataset) + def getImages(self, n): + top_n = itertools.islice(self.dataset.listChildren(), n) + return [Image(im) for im in top_n] + class Image: def __init__(self, image_wrapper): self.image = image_wrapper diff --git a/install.sh b/install.sh new file mode 100644 index 00000000..638039e7 --- /dev/null +++ b/install.sh @@ -0,0 +1,6 @@ +sudo apt-get install libbz2-dev # Install bzip headers +sudo apt-get install libssl1.0-dev # Install openssl headers +conda install openssl==1.0.2n # Install local openssl to match +pip install --no-cache-dir zeroc-ice==3.6.5 +python connect_to_omero.py + diff --git a/omero_py/__init__.py b/omero_py/__init__.py new file mode 100644 index 00000000..d7648721 --- /dev/null +++ b/omero_py/__init__.py @@ -0,0 +1,5 @@ +import os +THISPATH = os.path.dirname(os.path.abspath(__file__)) + +import sys +sys.path.insert(0, THISPATH) diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/connect_to_omero.py b/test/connect_to_omero.py index 92a56da7..d91eece9 100644 --- a/test/connect_to_omero.py +++ b/test/connect_to_omero.py @@ -7,13 +7,13 @@ # All Rights Reserved. # Use is subject to license terms supplied in LICENSE.txt # +from __future__ import print_function -""" -FOR TRAINING PURPOSES ONLY! -""" -import sys -sys.path.insert(0, './omero_py') - +# TODO remove and use unittest to run tests +import os +import sys +sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) +import omero_py USERNAME = 'upload' PASSWORD = '***REMOVED***' @@ -26,12 +26,12 @@ def print_obj(obj, indent=0): Helper method to display info about OMERO objects. Not all objects will have a "name" or owner field. """ - print """%s%s:%s Name:"%s" (owner=%s)""" % ( + print("""%s%s:%s Name:"%s" (owner=%s)""" % ( " " * indent, obj.OMERO_CLASS, obj.getId(), obj.getName(), - obj.getAnnotation()) + obj.getAnnotation())) if __name__ == '__main__': @@ -74,40 +74,40 @@ if __name__ == '__main__': # clients. user = conn.getUser() - print "Current user:" - print " ID:", user.getId() - print " Username:", user.getName() - print " Full Name:", user.getFullName() + print( "Current user:") + print( " ID:", user.getId()) + print( " Username:", user.getName()) + print( " Full Name:", user.getFullName()) # Check if you are an Administrator - print " Is Admin:", conn.isAdmin() + print( " Is Admin:", conn.isAdmin()) - print "Member of:" + print( "Member of:") for g in conn.getGroupsMemberOf(): - print " ID:", g.getId(), " Name:", g.getName() + print( " ID:", g.getId(), " Name:", g.getName()) group = conn.getGroupFromContext() - print "Current group: ", group.getName() + print( "Current group: ", group.getName()) # List the group owners and other members owners, members = group.groupSummary() - print " Group owners:" + print( " Group owners:") for o in owners: - print " ID: %s UserName: %s Name: %s" % ( - o.getId(), o.getOmeName(), o.getFullName()) - print " Group members:" + print( " ID: %s UserName: %s Name: %s" % ( + o.getId(), o.getOmeName(), o.getFullName())) + print( " Group members:") for m in members: - print " ID: %s UserName: %s Name: %s" % ( - m.getId(), m.getOmeName(), m.getFullName()) + print( " ID: %s UserName: %s Name: %s" % ( + m.getId(), m.getOmeName(), m.getFullName())) - print "Owner of:" + print( "Owner of:") for g in conn.listOwnedGroups(): - print " ID: ", g.getId(), " Name:", g.getName() + print( " ID: ", g.getId(), " Name:", g.getName()) # New in OMERO 5 - print "Admins:" + print( "Admins:") for exp in conn.getAdministrators(): - print " ID: %s UserName: %s Name: %s" % ( - exp.getId(), exp.getOmeName(), exp.getFullName()) + print( " ID: %s UserName: %s Name: %s" % ( + exp.getId(), exp.getOmeName(), exp.getFullName())) # The 'context' of our current session ctx = conn.getEventContext() diff --git a/test/test_connections.py b/test/test_connections.py new file mode 100644 index 00000000..27923029 --- /dev/null +++ b/test/test_connections.py @@ -0,0 +1,59 @@ +""" +Testing suite for connection to OMERO +""" +# TODO use omero.gateway.scripts.testdb_create module +from __future__ import print_function + +import sys +print(sys.path) + +import unittest +import json + +import omero_py +from core.connect import Database, Dataset + +class TestConnections(unittest.TestCase): + + @classmethod + def setUpClass(cls): + with open('config.json', 'r') as fd: + config = json.load(fd) + cls._config = config + cls._db = Database(cls._config['user'], + cls._config['password'], + cls._config['host'], + cls._config['port']) + + @classmethod + def tearDownClass(cls): + cls._db.disconnect() + + def testConnection(self): + self.assertTrue(self._db.connect()) + + def testUser(self): + self.assertEquals(self._db.user['Username'], self._config['user']) + + def testDataset(self): + dataset = self._db.getDatasets(1) + self.assertTrue(dataset is not None) + # FIXME cannot do this as it is instanciated anew. + # self._ds = dataset + + def testImage(self): + dataset = self._db.getDatasets(1) + self.assertTrue(dataset is not None) + + #FIXME return single dataset + image = dataset[0].getImages(1) + self.assertTrue(image is not None) + # FIXME cannot do this as it is instanciated anew. + self._im = image + + def testRenderImage(self): + pass + + +if __name__ == "__main__": + unittest.main() -- GitLab