# HG changeset patch
# User ufz
# Date 1769439961 0
# Node ID 89fc1f215e77a8506c79d5defd655edbe5abe4b0
# Parent f5c4f523432dc3979d1a77b4e71acb2a04602f6a
planemo upload for repository https://github.com/Helmholtz-UFZ/galaxy-tools/tree/main/tools/omero commit 233f0e70cb20a02ec8530dbcfd5c7e70eef74476
diff -r f5c4f523432d -r 89fc1f215e77 README.md
--- a/README.md Fri Jun 13 20:47:38 2025 +0000
+++ b/README.md Mon Jan 26 15:06:01 2026 +0000
@@ -1,4 +1,4 @@
-# OMERO import images
+# OMERO suite toolbox
## Set up user credentials on Galaxy to connect to other omero instance
diff -r f5c4f523432d -r 89fc1f215e77 connect_omero.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/connect_omero.py Mon Jan 26 15:06:01 2026 +0000
@@ -0,0 +1,15 @@
+import sys
+
+import ezomero as ez
+from omero.gateway import BlitzGateway
+
+
+def establish_connection(uuid_key, usr, psw, host, port):
+ if uuid_key is not None:
+ conn = BlitzGateway(username="", passwd="", host=host, port=port, secure=True)
+ conn.connect(sUuid=uuid_key)
+ else:
+ conn = ez.connect(usr, psw, "", host, port, secure=True)
+ if not conn.connect():
+ sys.exit("ERROR: Failed to connect to OMERO server")
+ return conn
diff -r f5c4f523432d -r 89fc1f215e77 macros.xml
--- a/macros.xml Fri Jun 13 20:47:38 2025 +0000
+++ b/macros.xml Mon Jan 26 15:06:01 2026 +0000
@@ -2,13 +2,14 @@
5.18.03.0.1
- 23.0
+ 25.1ezomeropandas
+
@@ -18,9 +19,17 @@
openjdk
+
-
+
+
+
+
+
+
+
+
@@ -30,27 +39,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
--host '$omero_host'
--port $omero_port
-
-
-
+
+ #if $session_id.session_id_input== "yes"
+ --session_close $close_connection
+ #else
+ --session_close "True"
+ #end if
+
+
- **OMERO-suite Security Diclaimer:** To utilize the OMERO tools, the user must trust Galaxy instances.
- The configuration file, which contains your OMERO password and username, is stored in the job working directory.
- This directory only exists during the runtime of the job and should only be accessible by the system user that runs the job.
- However, please be aware that your username and password may be exposed to users with administrative rights.
- We are working on increasing the security of the OMERO suite
+ **OMERO-suite Security Notice**
+
+ To use the OMERO tools, you must trust the Galaxy instance hosting your job.
+ Your OMERO username and password are stored in a temporary configuration file during job execution.
+
+ This file is accessible only to the system account running the job,
+ but may in principle be viewed by Galaxy administrators with elevated rights.
+
+ The file is removed after job completion and is not persistently stored.
+ **We recommend using service-specific or temporary OMERO credentials whenever possible.**
+
+ We are actively working to further improve security,
+ for example by enabling the UUID-key authentication.
+ The European Galaxy Server is operated in compliance with the EU General Data Protection Regulation (GDPR).
\ No newline at end of file
diff -r f5c4f523432d -r 89fc1f215e77 omero_dataset_to_plate.py
--- a/omero_dataset_to_plate.py Fri Jun 13 20:47:38 2025 +0000
+++ b/omero_dataset_to_plate.py Mon Jan 26 15:06:01 2026 +0000
@@ -1,23 +1,60 @@
import argparse
import csv
-import json
+import os
import re
import sys
from collections import defaultdict
-
+from pathlib import Path
+from typing import Optional
import omero
-from omero.gateway import BlitzGateway
+from connect_omero import establish_connection
from omero.rtypes import rint, rstring
+# Import environmental variables
+usr = os.getenv("OMERO_USER")
+psw = os.getenv("OMERO_PASSWORD")
+uuid_key = os.getenv("UUID_SESSION_KEY")
+
-def convert_dataset_to_plate(host, user, pws, port, dataset_id, log_file, mapping_file, delete_dataset):
+def convert_dataset_to_plate(
+ host: str,
+ port: str,
+ dataset_id: str,
+ log_file: Path,
+ mapping_file: str,
+ delete_dataset: bool,
+ uuid_key: Optional[str] = None,
+ ses_close: Optional[bool] = True
+) -> str:
"""
Connect to OMERO server, convert a dataset to a plate using the specified well mapping file
+
+ Parameters
+ ----------
+ host : str
+ OMERO server host (i.e. OMERO address or domain name)"
+ port : int
+ OMERO server port (default:4064)
+ dataset_id : str
+ Dataset ID to convert plate
+ log_file : str
+ Output path for the log file
+ mapping_file: str
+ Tabular file mapping filenames to well positions (2 columns: filename, Well)
+ delete_dataset: bool
+ Input to delete the original dataset convert to plate or not
+ uuid_key : str, optional
+ OMERO UUID session key to connect without password
+ ses_close : bool
+ Decide if close or not the section after executing the script. Defaulf value is true, useful when connecting with the UUID session key.
+
+ Returns
+ -------
+ str
+ Return log file with info on the conversion
"""
- conn = BlitzGateway(user, pws, host=host, port=port, secure=True)
- if not conn.connect():
- sys.exit("ERROR: Failed to connect to OMERO server")
+ conn = establish_connection(uuid_key, usr, psw, host, port)
def log_message(message, status="INFO"):
with open(log_file, 'w') as f:
@@ -94,34 +131,28 @@
if delete_dataset is True:
conn.deleteObjects("Dataset", [dataset_id], wait=True)
log_message(f"Images from Dataset {dataset_id} successfully added to Plate {plate.id.val}")
- conn.close()
+ if ses_close:
+ conn.close()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Convert an OMERO dataset to a plate.")
- parser.add_argument("--credential-file", dest="credential_file", type=str, required=True,
- help="Credential file (JSON file with username and password for OMERO)")
- parser.add_argument('--host', required=True, help='OMERO host')
- parser.add_argument('--port', required=True, type=int, help='OMERO port')
+ parser.add_argument('--host', required=True, help="OMERO server host (i.e. OMERO address or domain name)")
+ parser.add_argument('--port', required=True, type=int, help="OMERO server port (default:4064)")
parser.add_argument('--dataset_id', type=int, required=True, help="Dataset ID to convert plate")
- parser.add_argument('--log_file', default='metadata_import_log.txt',
- help='Path to the log file')
- parser.add_argument('--mapping_file',
- help='Tabular file mapping filenames to well positions (2 columns: filename, Well)')
- parser.add_argument('--delete_dataset', action='store_true',
- help='Flag to delete the original dataset')
+ parser.add_argument('--log_file', default='metadata_import_log.txt', help="Output path for the log file")
+ parser.add_argument('--mapping_file', help='Tabular file mapping filenames to well positions (2 columns: filename, Well)')
+ parser.add_argument('--session_close', required=False, help='Namespace or title for the annotation')
+ parser.add_argument('--delete_dataset', action='store_true', help='Flag to delete the original dataset')
+
args = parser.parse_args()
- with open(args.credential_file, 'r') as f:
- crds = json.load(f)
-
convert_dataset_to_plate(
- user=crds['username'],
- pws=crds['password'],
host=args.host,
port=args.port,
dataset_id=args.dataset_id,
log_file=args.log_file,
mapping_file=args.mapping_file,
+ ses_close=args.session_close,
delete_dataset=args.delete_dataset
)
diff -r f5c4f523432d -r 89fc1f215e77 omero_filter.py
--- a/omero_filter.py Fri Jun 13 20:47:38 2025 +0000
+++ b/omero_filter.py Mon Jan 26 15:06:01 2026 +0000
@@ -1,16 +1,59 @@
import argparse
import csv
-import json
+import os
import sys
+from typing import Optional
import ezomero as ez
+from connect_omero import establish_connection
+
+# Import environmental variables
+usr = os.getenv("OMERO_USER")
+psw = os.getenv("OMERO_PASSWORD")
+uuid_key = os.getenv("UUID_SESSION_KEY")
-def filter_ids_ezo(user, pws, host, port, filter, id, value1, value2=None, tsv_file="filter_list.tsv"):
+def filter_ids_ezo(
+ host: str,
+ port: int,
+ filter: str,
+ id: list,
+ value1: str,
+ value2: Optional[str] = None,
+ uuid_key: Optional[str] = None,
+ tsv_file: str = "filter_list.tsv",
+ ses_close: Optional[bool] = True
+) -> int:
+ """
+
+ Apply filter_by_filename, filter_by_kv or filter_by_tag_value from the ezomero module to a list of images ID.
- # Transform the id input in a list of integer
- id = id.split(',')
- id = list(map(int, id))
+ Parameters
+ ----------
+ host : str
+ OMERO server host (i.e. OMERO address or domain name)"
+ port : int
+ OMERO server port (default:4064)
+ filter : str
+ Filter to apply to the IDs list (Filename, Key-Value pairs or Tags)
+ id : int
+ A list of image IDs
+ value1 : str
+ Primary filter value.
+ value2 : str, optional
+ Optional secondary filter value.
+ uuuid_key : str, optional
+ OMERO UUID session key to connect without password
+ tsv_file : str, optional
+ Output TSV filename. Default is "filter_list.tsv".
+ ses_close : bool
+ Decide if close or not the section after executing the script. Defaulf value is true, useful when connecting with the UUID session key.
+
+ Returns
+ -------
+ csv.writer
+ A CSV writer object configured to write TSV data. Contain a list of IDs with the filtered IDs
+ """
# Function to write tabular file from the ezomero output
def write_ids_to_tsv(data):
@@ -19,8 +62,15 @@
for item in data:
writer.writerow([item]) # Write each ID
- with ez.connect(user, pws, "", host, port, secure=True) as conn:
+ # Try to connect with UUID or with username and password
+ conn = establish_connection(uuid_key, usr, psw, host, port)
+ # Transform the id input in a list of integer
+ id = id.split(',')
+ id = list(map(int, id))
+
+ try:
+ # Apply different filters to the image ID list
if filter == "filename":
fn_ids = ez.filter_by_filename(conn, id, value1)
write_ids_to_tsv(fn_ids)
@@ -39,39 +89,34 @@
else:
sys.exit(f"Unsupported object type: {filter}")
+ finally:
+ if ses_close:
+ conn.close()
-# Argument parsing
+
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Fetch and save data as TSV based on object type.")
- parser.add_argument("--credential-file", dest="credential_file", type=str, required=True,
- help="Credential file (JSON file with username and password for OMERO)")
- parser.add_argument('--host', required=True,
- help="Host server address.")
- parser.add_argument('--port', required=True, type=int,
- help='OMERO port')
- parser.add_argument('--filter', required=True,
- help="Filter type - Filename, Key-Value Pairs, Tag")
- parser.add_argument('--id', required=True,
- help="List of images IDs")
- parser.add_argument('--value1', required=True,
- help="First searching values - Filename, Key, Tag")
+ parser.add_argument('--host', required=True, help="OMERO server host (i.e. OMERO address or domain name)")
+ parser.add_argument('--port', required=True, type=int, help="OMERO server port (default:4064)")
+ parser.add_argument('--filter', required=True, help="Filter type - Filename, Key-Value Pairs, Tag")
+ parser.add_argument('--id', required=True, help="List of images IDs")
+ parser.add_argument('--value1', required=True, help="First searching values - Filename, Key, Tag")
parser.add_argument('--value2', required=False,
help="Second searching values - Value (necessary just for Key-Value Pairs filter")
- parser.add_argument('--tsv_file', default='filter_list.tsv',
- help="Output TSV file path.")
+ parser.add_argument('--session_close', required=False, help='Namespace or title for the annotation')
+ parser.add_argument('--tsv_file', default='filter_list.tsv', help="Output TSV file path.")
+
args = parser.parse_args()
if args.filter == "KP" and args.value2 is None:
raise ValueError("'--value 2' is necessary to retrieve KP")
- with open(args.credential_file, 'r') as f:
- crds = json.load(f)
-
# Call the main function to get the object and save it as a TSV
- filter_ids_ezo(user=crds['username'], pws=crds['password'], host=args.host,
+ filter_ids_ezo(host=args.host,
port=args.port,
filter=args.filter,
value1=args.value1,
value2=args.value2,
id=args.id,
+ ses_close=args.session_close,
tsv_file=args.tsv_file)
diff -r f5c4f523432d -r 89fc1f215e77 omero_get_id.py
--- a/omero_get_id.py Fri Jun 13 20:47:38 2025 +0000
+++ b/omero_get_id.py Mon Jan 26 15:06:01 2026 +0000
@@ -1,12 +1,57 @@
import argparse
import csv
-import json
+import os
import sys
+from typing import Optional
import ezomero as ez
+from connect_omero import establish_connection
+
+# Import environmental variables
+usr = os.getenv("OMERO_USER")
+psw = os.getenv("OMERO_PASSWORD")
+uuid_key = os.getenv("UUID_SESSION_KEY")
-def get_ids_ezo(user, pws, host, port, final_obj_type, parent_obj_type, parent_id=None, tsv_file="id_list.tsv"):
+def get_ids_ezo(
+ host: str,
+ port: int,
+ final_obj_type: str,
+ parent_obj_type: str,
+ parent_id: Optional[int] = None,
+ uuid_key: Optional[str] = None,
+ tsv_file: str = "filter_list.tsv",
+ ses_close: Optional[bool] = True
+) -> int:
+ """
+ Fetch OMERO object IDs (Project, Dataset, Image, Annotation, Tag, ROI, or Table) as TSV from parent object (roject, Dataset, Plate, Well, Image)
+
+ Parameters
+ ----------
+ host : str
+ OMERO server host (i.e. OMERO address or domain name)"
+ port : int
+ OMERO server port (default:4064)
+ final_obj_type : str
+ Type of object to fetch ID: Project, Dataset, Image, Annotation, Tag, ROI, or Table.
+ parent_obj_type : int
+ Type of object from which you fetch IDs: Project, Dataset, Plate, Well, Image (or 'All' if you want to get all objects).
+ parent_id : str, optional
+ ID of the OMERO object in `--parent_obj_type`, not required if you used `--parent_obj_type All`.
+ uuid_key : str, optional
+ OMERO UUID session key to connect without password
+ tsv_file : str, optional
+ Output TSV filename. Default is "filter_list.tsv".
+ ses_close : bool
+ Decide if close or not the section after executing the script. Defaulf value is true, useful when connecting with the UUID session key.
+
+ Returns
+ -------
+ csv.writer
+ A CSV writer object configured to write TSV data. Contain a list of IDs.
+ """
+
+ conn = establish_connection(uuid_key, usr, psw, host, port)
# Function to write tabular file from the ezomero output
def write_ids_to_tsv(data):
@@ -15,8 +60,8 @@
for item in data:
writer.writerow([item]) # Write each ID
- with ez.connect(user, pws, "", host, port, secure=True) as conn:
-
+ try:
+ # Fetch different object according to the user input
if final_obj_type == "Project":
proj_ids = ez.get_project_ids(conn)
write_ids_to_tsv(proj_ids)
@@ -75,42 +120,40 @@
else:
sys.exit(f"Unsupported object type: {filter}")
+ finally:
+ if ses_close:
+ conn.close()
-# Argument parsing
+
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Fetch OMERO object IDs as TSV from parent object.")
- parser.add_argument("--credential-file", dest="credential_file", type=str,
- required=True, help="Credential file (JSON file with username and password for OMERO)")
- parser.add_argument('--host', required=True,
- help="Host server address.")
- parser.add_argument('--port', required=True, type=int,
- help='OMERO port')
+ parser.add_argument('--host', required=True, help="OMERO server host (i.e. OMERO address or domain name)")
+ parser.add_argument('--port', required=True, type=int, help="OMERO server port (default:4064)")
parser.add_argument('--final_obj_type', required=True,
help="Type of object to fetch ID: Project, Dataset, Image, Annotation, Tag, Roi, or Table.")
parser.add_argument('--parent_obj_type', required=True,
help="Type of object from which you fetch IDs: Project, Dataset, Plate, Well, Image (or 'All' if you want to get all objects).")
parser.add_argument('--parent_id', required=False, type=int,
help="ID of the OMERO object in `--parent_obj_type`, not required if you used `--parent_obj_type All`.")
- parser.add_argument('--tsv_file', default='id_list.tsv',
- help="Output TSV file path.")
+ parser.add_argument('--session_close', required=False, help='Namespace or title for the annotation')
+ parser.add_argument('--tsv_file', default='id_list.tsv', help="Output TSV file path.")
+
args = parser.parse_args()
if args.parent_id is None and args.parent_obj_type != "All":
raise ValueError("ID is only optional is you use `--parent_obj_type All`")
if args.final_obj_type == "Roi" and args.parent_obj_type != "Image":
- raise ValueError("Roi IDs can only be retrived from images, use `--parent_obj_type Image`")
+ raise ValueError("ROI IDs can only be retrived from images, use `--parent_obj_type Image`")
if args.parent_obj_type == "All" and args.final_obj_type not in ["Image", "Dataset", "Project"]:
raise ValueError("Only Images, Datasets and Projects is compatible with `--parent_obj_type All`")
- with open(args.credential_file, 'r') as f:
- crds = json.load(f)
-
# Call the main function to get the object and save it as a TSV
- get_ids_ezo(user=crds['username'], pws=crds['password'], host=args.host,
+ get_ids_ezo(host=args.host,
port=args.port,
final_obj_type=args.final_obj_type,
parent_obj_type=args.parent_obj_type,
parent_id=args.parent_id,
+ ses_close=args.session_close,
tsv_file=args.tsv_file)
diff -r f5c4f523432d -r 89fc1f215e77 omero_get_value.py
--- a/omero_get_value.py Fri Jun 13 20:47:38 2025 +0000
+++ b/omero_get_value.py Mon Jan 26 15:06:01 2026 +0000
@@ -1,14 +1,56 @@
import argparse
import csv
-import json
import os
import sys
+from typing import Optional
import ezomero as ez
import pandas as pd
+from connect_omero import establish_connection
+
+# Import environmental variables
+usr = os.getenv("OMERO_USER")
+psw = os.getenv("OMERO_PASSWORD")
+uuid_key = os.getenv("UUID_SESSION_KEY")
-def get_object_ezo(user, pws, host, port, obj_type, ids, out_dir):
+def get_object_ezo(
+ host: str,
+ port: int,
+ obj_type: str,
+ ids: list,
+ out_dir: str,
+ uuid_key: Optional[str] = None,
+ ses_close: Optional[bool] = True
+) -> str | dict:
+
+ """
+Fetch OMERO objects (Annotation, Table and Key-Value Pairs list) and save them as TSV based on object type.
+
+Parameters
+----------
+host : str
+ OMERO server host (i.e. OMERO address or domain name)"
+port : int
+ OMERO server port (default:4064)
+obj_type : str
+ Type of object to fetch ID: Project, Dataset, Image, Annotation, Tag, ROI, or Table.
+ids : list
+ IDs of the OMERO objects.
+out_dir : str
+ Output path of the file
+uuid_key : str, optional
+ OMERO UUID session key to connect without password
+ses_close : bool
+ Decide if close or not the section after executing the script. Defaulf value is true, useful when connecting with the UUID session key.
+Returns
+-------
+csv.writer
+ A CSV writer object configured to write TSV data.
+"""
+
+ conn = establish_connection(uuid_key, usr, psw, host, port)
+
# Function to write tabular file from the ezomero output
def write_values_to_tsv(data, header):
with open("output.tsv", 'w', newline='') as f:
@@ -31,7 +73,8 @@
for row in data:
f.write('\t'.join([str(val) for val in row]) + '\n')
- with ez.connect(user, pws, "", host, port, secure=True) as conn:
+ try:
+ # Fetch different object according to the user input
if obj_type == "Annotation":
ma_dict = {}
for maid in ids:
@@ -61,25 +104,22 @@
else:
sys.exit(f"Unsupported object type: {filter}")
+ finally:
+ if ses_close:
+ conn.close()
-# Argument parsing
+
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Fetch and save data as TSV based on object type.")
- parser.add_argument("--credential-file", dest="credential_file", type=str,
- required=True, help="Credential file (JSON file with username and password for OMERO)")
- parser.add_argument('--host', required=True,
- help="Host server address.")
- parser.add_argument('--port', required=True, type=int,
- help='OMERO port')
- parser.add_argument('--obj_type', required=True,
- help="Type of object to fetch: Annotation, Table or Tag.")
+ parser.add_argument('--host', required=True, help="OMERO server host (i.e. OMERO address or domain name)")
+ parser.add_argument('--port', required=True, type=int, help="OMERO server port (default:4064)")
+ parser.add_argument('--obj_type', required=True, help="Type of object to fetch: Annotation, Table or Tag.")
group = parser.add_mutually_exclusive_group()
- group.add_argument('--ids', nargs='+', type=int,
- help="IDs of the OMERO objects.")
- group.add_argument('--ids_path',
- help="File with IDs of the OMERO objects (one per line).")
- parser.add_argument('--out_dir', required=True,
- help="Output path.")
+ group.add_argument('--ids', nargs='+', type=int, help="IDs of the OMERO objects.")
+ group.add_argument('--ids_path', help="File with IDs of the OMERO objects (one per line).")
+ parser.add_argument('--session_close', required=False, help='Namespace or title for the annotation')
+ parser.add_argument('--out_dir', required=True, help="Output path.")
+
args = parser.parse_args()
if args.ids_path:
@@ -93,12 +133,10 @@
if len(args.ids) == 0:
raise ValueError("Cound not find a single ID in the file.")
- with open(args.credential_file, 'r') as f:
- crds = json.load(f)
-
# Call the main function to get the object and save it as a TSV
- get_object_ezo(user=crds['username'], pws=crds['password'], host=args.host,
+ get_object_ezo(host=args.host,
port=args.port,
obj_type=args.obj_type,
ids=args.ids,
+ ses_close=args.session_close,
out_dir=args.out_dir)
diff -r f5c4f523432d -r 89fc1f215e77 omero_get_value.xml
--- a/omero_get_value.xml Fri Jun 13 20:47:38 2025 +0000
+++ b/omero_get_value.xml Mon Jan 26 15:06:01 2026 +0000
@@ -2,16 +2,24 @@
with ezomero macros.xml
- 2
+ 3omero
+
+
+
+
-
-
-
@@ -155,4 +161,4 @@
10.1038/nmeth.1896
-
+
\ No newline at end of file
diff -r f5c4f523432d -r 89fc1f215e77 omero_metadata_upload.py
--- a/omero_metadata_upload.py Fri Jun 13 20:47:38 2025 +0000
+++ b/omero_metadata_upload.py Mon Jan 26 15:06:01 2026 +0000
@@ -1,13 +1,66 @@
import argparse
-import json
+import os
from datetime import datetime
+from pathlib import Path
+from typing import Optional
import ezomero as ez
import pandas as pd
+from connect_omero import establish_connection
+
+# Import environmental variables
+usr = os.getenv("OMERO_USER")
+psw = os.getenv("OMERO_PASSWORD")
+uuid = os.getenv("UUID_SESSION_KEY")
-def metadata_import_ezo(user, pws, host, port, obj_type, did=None, ann_type="table", ann_file=None, an_name=None,
- log_file='metadata_import_log.txt'):
+def metadata_import_ezo(
+ host: str,
+ port: int,
+ obj_type: str,
+ ann_type: [str] = "table",
+ ann_file: Path = None,
+ an_name: [str] = None,
+ did: Optional[int] = None,
+ uuid_key: Optional[str] = None,
+ log_file: [str] = 'metadata_import_log.txt',
+ ses_close: Optional[bool] = True,
+) -> str:
+
+ '''
+ Import metadata into OMERO as form of OMERO.table or Key-Value Pairs.
+
+ Parameters
+ ----------
+ host : str
+ OMERO server host (i.e. OMERO address or domain name)"
+ port : int
+ OMERO server port (default:4064)
+ did: list
+ ID of the object (if it exists)
+ obj_type : str
+ Annotation type meaning Table or Key-Value pairs
+ ann_type: str
+ Path to the annotation file
+ ann_file: [Path]=None
+ Path to the annotation file
+ an_name : str
+ Namespace or title for the annotation
+ uuid_key : str, optional
+ OMERO UUID session key to connect without password
+ log_file : str
+ Output path for the log file
+ ses_close : bool
+ Decide if close or not the section after executing the script. Defaulf value is true, useful when connecting with the UUID session key.
+
+ Returns
+ -------
+ csv.writer
+ A CSV writer object configured to write TSV data.
+ '''
+
+ conn = establish_connection(uuid_key, usr, psw, host, port)
+
def upload_metadata(conn, obj_type, did, data_dict, df, ann_type, an_name):
try:
if ann_type == "KV":
@@ -48,59 +101,60 @@
data_dict = ann_file
try:
- with ez.connect(user, pws, "", host, port, secure=True) as conn:
- if obj_type == "project":
- if did is None:
- did = ez.post_project(conn, project_name=str(datetime.now()))
- result = upload_metadata(conn, "Project", did, data_dict, df, ann_type, an_name)
- elif obj_type == "screen":
- if did is None:
- did = ez.post_screen(conn, screen_name=str(datetime.now()))
- result = upload_metadata(conn, "Screen", did, data_dict, df, ann_type, an_name)
- elif obj_type == "dataset":
- if did is None:
- did = ez.post_dataset(conn, dataset_name=str(datetime.now()))
- result = upload_metadata(conn, "Dataset", did, data_dict, df, ann_type, an_name)
- elif obj_type == "plate":
- result = upload_metadata(conn, "Plate", did, data_dict, df, ann_type, an_name)
- elif obj_type == "well":
- result = upload_metadata(conn, "Well", did, data_dict, df, ann_type, an_name)
- elif obj_type == "image":
- result = upload_metadata(conn, "Image", did, data_dict, df, ann_type, an_name)
- else:
- raise ValueError("Unsupported object type provided: {}".format(obj_type))
-
- if result is not None:
- log_success(f"Successfully uploaded metadata for {obj_type} with ID {did}. Result: {result}")
- else:
- log_error(f"Failed to upload metadata for {obj_type} with ID {did}.")
-
- conn.close()
-
- except Exception as e:
- log_error(f"Connection error: {str(e)}")
+ if obj_type == "project":
+ if did is None:
+ did = ez.post_project(conn, project_name=str(datetime.now()))
+ result = upload_metadata(conn, "Project", did, data_dict, df, ann_type, an_name)
+ elif obj_type == "screen":
+ if did is None:
+ did = ez.post_screen(conn, screen_name=str(datetime.now()))
+ result = upload_metadata(conn, "Screen", did, data_dict, df, ann_type, an_name)
+ elif obj_type == "dataset":
+ if did is None:
+ did = ez.post_dataset(conn, dataset_name=str(datetime.now()))
+ result = upload_metadata(conn, "Dataset", did, data_dict, df, ann_type, an_name)
+ elif obj_type == "plate":
+ result = upload_metadata(conn, "Plate", did, data_dict, df, ann_type, an_name)
+ elif obj_type == "well":
+ result = upload_metadata(conn, "Well", did, data_dict, df, ann_type, an_name)
+ elif obj_type == "image":
+ result = upload_metadata(conn, "Image", did, data_dict, df, ann_type, an_name)
+ else:
+ raise ValueError("Unsupported object type provided: {}".format(obj_type))
+ finally:
+ if result is not None:
+ log_success(f"Successfully uploaded metadata for {obj_type} with ID {did}. Result: {result}")
+ if ses_close:
+ conn.close()
+ else:
+ log_error(f"Failed to upload metadata for {obj_type} with ID {did}.")
+ if ses_close:
+ conn.close()
if __name__ == "__main__":
- parser = argparse.ArgumentParser(description='Import metadata into OMERO.')
- parser.add_argument("--credential-file", dest="credential_file", type=str, required=True,
- help="Credential file (JSON file with username and password for OMERO)")
- parser.add_argument('--host', required=True, help='OMERO host')
- parser.add_argument('--port', required=True, type=int, help='OMERO port')
- parser.add_argument('--obj_type', required=True, choices=['project', 'screen', 'dataset', 'plate',
- 'well ', 'image'],
+ parser = argparse.ArgumentParser(
+ description='Import metadata into OMERO as form of OMERO.table or Key-Value Pairs.')
+ parser.add_argument('--host', required=True, help="OMERO server host (i.e. OMERO address or domain name)")
+ parser.add_argument('--port', required=True, type=int, help="OMERO server port (default:4064)")
+ parser.add_argument('--obj_type', required=True,
+ choices=['project', 'screen', 'dataset', 'plate', 'well ', 'image'],
help='Type of OMERO object')
parser.add_argument('--did', type=int, help='ID of the object (if it exists)')
parser.add_argument('--ann_type', required=True, choices=['table', 'KV', "attachement"], help='Annotation type')
parser.add_argument('--ann_file', required=True, help='Path to the annotation file')
parser.add_argument('--an_name', required=True, help='Namespace or title for the annotation')
+ parser.add_argument('--session_close', required=False, help='Namespace or title for the annotation')
parser.add_argument('--log_file', default='metadata_import_log.txt', help='Path to the log file')
args = parser.parse_args()
- with open(args.credential_file, 'r') as f:
- crds = json.load(f)
-
- metadata_import_ezo(user=crds['username'], pws=crds['password'], host=args.host, port=args.port,
- obj_type=args.obj_type, did=args.did, ann_type=args.ann_type,
- ann_file=args.ann_file, an_name=args.an_name, log_file=args.log_file)
+ metadata_import_ezo(host=args.host,
+ port=args.port,
+ obj_type=args.obj_type,
+ did=args.did,
+ ann_type=args.ann_type,
+ ann_file=args.ann_file,
+ an_name=args.an_name,
+ ses_close=args.session_close,
+ log_file=args.log_file)
diff -r f5c4f523432d -r 89fc1f215e77 omero_roi_upload.py
--- a/omero_roi_upload.py Fri Jun 13 20:47:38 2025 +0000
+++ b/omero_roi_upload.py Mon Jan 26 15:06:01 2026 +0000
@@ -1,12 +1,20 @@
import argparse
-import json
+import os
import re
+from pathlib import Path
+from typing import Optional
+import ezomero as ez
import numpy as np
import pandas as pd
-from ezomero import connect, post_roi
+from connect_omero import establish_connection
from ezomero.rois import Ellipse, Label, Line, Point, Polygon, Polyline, Rectangle
+# Import environmental variables
+usr = os.getenv("OMERO_USER")
+psw = os.getenv("OMERO_PASSWORD")
+uuid_key = os.getenv("UUID_SESSION_KEY")
+
def parse_color(color_str):
if not color_str:
@@ -24,6 +32,7 @@
return [tuple(map(float, point.split(','))) for point in points]
+# function to create different shapes
def create_shape(row):
shape_type = row['shape']
shape = None
@@ -122,55 +131,85 @@
return shape
-def main(input_file, conn, image_id, log_file):
+def import_rois(
+ host: str,
+ port: int,
+ input_file: Path,
+ image_id: int,
+ log_file: Path,
+ uuid_key: Optional[str] = None,
+ ses_close: Optional[bool] = True,
+) -> str | int:
+
+ """
+ Create shapes from a tabular file and upload them as an ROI to OMERO.
+
+ Parameters
+ ----------
+ host : str
+ OMERO server host (i.e. OMERO address or domain name)"
+ port : int
+ OMERO server port (default:4064)
+ image_id : str
+ ID of the image to which the ROI will be linked
+ input_file: Path
+ Path to the input tabular file
+ log_file : str
+ Output path for the log file
+ uuid_key : str, optional
+ OMERO UUID session key to connect without password
+ ses_close : bool
+ Decide if close or not the section after executing the script. Defaulf value is true, useful when connecting with the UUID session key.
+ Returns
+ -------
+ str | int
+ A CSV writer object configured to write TSV data and ID of newly created ROI
+ """
+
+ # Try to connect with UUID or with username and password
+ conn = establish_connection(uuid_key, usr, psw, host, port)
+
# Open log file
- with open(log_file, 'w') as log:
- df = pd.read_csv(input_file, sep='\t')
- # Replace nan to none
- df = df.replace({np.nan: None})
- for index, row in df.iterrows():
- msg = f"Processing row {index + 1}/{len(df)}: {row.to_dict()}"
- print(msg)
- log.write(msg + "\n")
- shape = create_shape(row)
- if shape:
- roi_name = row['roi_name'] if 'roi_name' in row else None
- roi_description = row['roi_description'] if 'roi_description' in row else None
- roi_id = post_roi(conn, image_id, [shape], name=roi_name, description=roi_description)
- msg = f"ROI ID: {roi_id} for row {index + 1}"
+ try:
+ with open(log_file, 'w') as log:
+ df = pd.read_csv(input_file, sep='\t')
+ # Replace nan to none
+ df = df.replace({np.nan: None})
+ for index, row in df.iterrows():
+ msg = f"Processing row {index + 1}/{len(df)}: {row.to_dict()}"
print(msg)
log.write(msg + "\n")
- else:
- msg = f"Skipping row {index + 1}: Unable to create shape"
- print(msg)
- log.write(msg + "\n")
+ shape = create_shape(row)
+ if shape:
+ roi_name = row['roi_name'] if 'roi_name' in row else None
+ roi_description = row['roi_description'] if 'roi_description' in row else None
+ roi_id = ez.post_roi(conn, image_id, [shape], name=roi_name, description=roi_description)
+ msg = f"ROI ID: {roi_id} for row {index + 1}"
+ print(msg)
+ log.write(msg + "\n")
+ else:
+ msg = f"Skipping row {index + 1}: Unable to create shape"
+ print(msg)
+ log.write(msg + "\n")
+ finally:
+ if ses_close:
+ conn.close()
if __name__ == "__main__":
- parser = argparse.ArgumentParser(
- description="Create shapes from a tabular file and optionally post them as an ROI to OMERO.")
+ parser = argparse.ArgumentParser(description="Create shapes from a tabular file and post them as an ROI to OMERO.")
+ parser.add_argument("--host", type=str, required=True, help="OMERO server host (i.e. OMERO address or domain name)")
+ parser.add_argument("--port", type=int, default=4064, help="OMERO server port (default:4064)")
parser.add_argument("--input_file", help="Path to the input tabular file.")
parser.add_argument("--image_id", type=int, required=True, help="ID of the image to which the ROI will be linked")
- parser.add_argument("--host", type=str, required=True, help="OMERO server host")
- parser.add_argument("--credential-file", dest="credential_file", type=str, required=True, help="Credential file (JSON file with username and password for OMERO)")
- parser.add_argument("--port", type=int, default=4064, help="OMERO server port")
- parser.add_argument("--log_file", type=str, default="process.txt", help="Log file path")
+ parser.add_argument('--session_close', required=False, help='Namespace or title for the annotation')
+ parser.add_argument("--log_file", type=str, default="process.txt", help="Output path for the log file")
args = parser.parse_args()
- with open(args.credential_file, 'r') as f:
- crds = json.load(f)
-
- conn = connect(
- host=args.host,
- user=crds['username'],
- password=crds['password'],
- port=args.port,
- group="",
- secure=True
- )
-
- try:
- main(args.input_file, conn, args.image_id, args.log_file)
- finally:
- conn.close()
+ import_rois(host=args.host,
+ port=args.port,
+ input_file=args.input_file,
+ image_id=args.image_id,
+ ses_close=args.session_close,
+ log_file=args.log_file)
diff -r f5c4f523432d -r 89fc1f215e77 test-data/omero_output_2.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/omero_output_2.json Mon Jan 26 15:06:01 2026 +0000
@@ -0,0 +1,3 @@
+[{"#": "0", "Class": "DatasetI", "Id": "3", "details": "owner=0;group=0", "name": "galaxy_test_upload"},
+{"#": "1", "Class": "DatasetI", "Id": "2", "details": "owner=0;group=0", "name": "test_hcs_dts"},
+{"#": "2", "Class": "DatasetI", "Id": "1", "details": "owner=0;group=0", "name": "test_dts"}]