Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update #18

Merged
merged 15 commits into from
Apr 25, 2024
4 changes: 2 additions & 2 deletions .github/workflows/omero_plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ jobs:
env:
STAGE: cli
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Checkout omero-test-infra
uses: actions/checkout@master
with:
repository: ome/omero-test-infra
path: .omero
ref: ${{ secrets.OMERO_TEST_INFRA_REF }}
- name: Build and run OMERO tests
run: .omero/docker $STAGE
run: PLUGIN=mkngff .omero/docker $STAGE
12 changes: 7 additions & 5 deletions .github/workflows/publish_pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ jobs:
name: Build and publish Python distribution to PyPI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.9'
- name: Build a binary wheel and a source tarball
run: |
python -mpip install wheel
python setup.py sdist bdist_wheel
python -mpip install build
python -m build
- name: Publish distribution to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@v1.3.0
uses: pypa/gh-action-pypi-publish@v1.8.14
with:
password: ${{ secrets.PYPI_PASSWORD }}
20 changes: 12 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,26 @@ repos:
- id: seed-isort-config

- repo: https://github.com/PyCQA/isort
rev: 5.10.1
rev: 5.13.2
hooks:
- id: isort
args: ["--profile", "black"]

- repo: https://github.com/psf/black
rev: 23.3.0
rev: 24.3.0
hooks:
- id: black
args: [--target-version=py36]

- repo: https://github.com/asottile/pyupgrade
rev: v2.29.1
rev: v3.15.1
hooks:
- id: pyupgrade
args:
- --py36-plus

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
rev: v4.5.0
hooks:
- id: trailing-whitespace
exclude: .bumpversion.cfg
Expand All @@ -45,7 +45,7 @@ repos:
- --autofix

- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
rev: 7.0.0
hooks:
- id: flake8
additional_dependencies: [
Expand All @@ -63,13 +63,17 @@ repos:
]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.971
rev: v1.9.0
hooks:
- id: mypy
language_version: python3
args: [
--disallow-untyped-defs,
--ignore-missing-imports,
]
exclude: test/

- repo: https://github.com/adrienverge/yamllint.git
rev: v1.26.3
rev: v1.35.1
hooks:
- id: yamllint
# args: [--config-data=relaxed]
Expand Down
9 changes: 4 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
.. image:: https://github.com/ome/omero-mkngff/workflows/OMERO/badge.svg
:target: https://github.com/ome/omero-mkngff

.. image:: https://github.com/IDR/omero-mkngff/workflows/OMERO/badge.svg
:target: https://github.com/IDR/omero-mkngff
.. image:: https://badge.fury.io/py/omero-mkngff.svg
:target: https://badge.fury.io/py/omero-mkngff

omero-mkngff
==================================
============

Plugin to swap OMERO filesets with NGFF

Expand Down Expand Up @@ -86,4 +85,4 @@ licensed under the terms of the GNU General Public License (GPL) v2 or later.
Copyright
---------

2017-2020, The Open Microscopy Environment
2023-2024, The Open Microscopy Environment
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[metadata]
description-file = README.rst
description_file = README.rst

[mypy]
check_untyped_defs = true
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def read(fname):


version = "0.1.0.dev0"
url = "https://github.com/ome/omero-mkngff"
url = "https://github.com/IDR/omero-mkngff"

setup(
version=version,
Expand Down
101 changes: 64 additions & 37 deletions src/omero_mkngff/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@
omero mkngff sql ${fileset} ${zarrdir} --zarr_name "nice.ome.zarr"

"""
FS_SUFFIX_HELP = ("New Fileset.templatePrefix will be old Fileset.templatePrefix + fs_suffix. "
"Default is to use _mkngff. "
"Use 'None' to specify an empty string (new templatePrefix is same as old).")
FS_SUFFIX_HELP = (
"New Fileset.templatePrefix will be old Fileset.templatePrefix + fs_suffix. "
"Default is to use _mkngff. "
"Use 'None' to specify an empty string (new templatePrefix is same as old)."
)

SETUP = """

Expand Down Expand Up @@ -151,42 +153,59 @@ def _configure(self, parser: Parser) -> None:

sql = sub.add_parser("sql", help="generate SQL statement")
sql.add_argument(
"--secret", help="DB UUID for protecting SQL statements", default="SECRETUUID"
"--secret",
help="DB UUID for protecting SQL statements",
default="SECRETUUID",
)
sql.add_argument("--zarr_name", help="Nicer name for zarr directory if desired")
sql.add_argument(
"--symlink_repo",
help=("Create symlinks from Fileset to symlink_target using"
"this ManagedRepo path, e.g. /data/OMERO/ManagedRepository")
help=(
"Create symlinks from Fileset to symlink_target using"
"this ManagedRepo path, e.g. /data/OMERO/ManagedRepository"
),
)
sql.add_argument(
"--bfoptions", action="store_true",
help=("Create data.zarr.bfoptions file if --symlink_repo has been provided")
"--bfoptions",
action="store_true",
help=(
"Create data.zarr.bfoptions file if --symlink_repo has been provided"
),
)
sql.add_argument(
"--clientpath",
help=("Base path to create clientpath/path/to/img.zarr/")
"--clientpath", help=("Base path to create clientpath/path/to/img.zarr/")
)
sql.add_argument("--fs_suffix", default="_mkngff", help=FS_SUFFIX_HELP)
sql.add_argument("fileset_id", type=int)
sql.add_argument("symlink_target")
sql.set_defaults(func=self.sql)

# symlink command to ONLY create symlinks - useful if you have previously generated
# symlink command to ONLY create symlinks
# useful if you have previously generated
# the corresponding sql for a Fileset
symlink = sub.add_parser("symlink", help="Create managed repo symlink")
symlink.add_argument("symlink_repo", help=(
"Create symlinks from Fileset to symlink_target using"
"this ManagedRepo path, e.g. /data/OMERO/ManagedRepository"))
symlink.add_argument(
"symlink_repo",
help=(
"Create symlinks from Fileset to symlink_target using"
"this ManagedRepo path, e.g. /data/OMERO/ManagedRepository"
),
)
symlink.add_argument("fileset_id", type=int)
symlink.add_argument("symlink_target")
symlink.add_argument("--bfoptions", action="store_true", help="Create data.zarr.bfoptions file")
symlink.add_argument(
"--bfoptions", action="store_true", help="Create data.zarr.bfoptions file"
)
symlink.add_argument("--fs_suffix", default="_mkngff", help=FS_SUFFIX_HELP)
symlink.set_defaults(func=self.symlink)

bfoptions = sub.add_parser("bfoptions", help="Create data.zarr.bfoptions in Fileset")
bfoptions.add_argument("symlink_repo", help=(
"The ManagedRepo path, e.g. /data/OMERO/ManagedRepository"))
bfoptions = sub.add_parser(
"bfoptions", help="Create data.zarr.bfoptions in Fileset"
)
bfoptions.add_argument(
"symlink_repo",
help=("The ManagedRepo path, e.g. /data/OMERO/ManagedRepository"),
)
bfoptions.add_argument("fileset_id", type=int)
bfoptions.add_argument("symlink_target")
bfoptions.add_argument("--fs_suffix", default="_mkngff", help=FS_SUFFIX_HELP)
Expand All @@ -207,11 +226,14 @@ def sql(self, args: Namespace) -> None:
self.ctx.die(401, f"Symlink target does not exist: {args.symlink_target}")
return

# If symlink dir exists, we assume that this fileset has been processed -> skip...
# If symlink dir exists, we assume that
# this fileset has been processed -> skip...
if args.symlink_repo:
symlink_dir = self.get_symlink_dir(args.symlink_repo, prefix)
if os.path.exists(symlink_dir):
self.ctx.err(f"Symlink dir exists at {symlink_dir} - skipping sql output")
self.ctx.err(
f"Symlink dir exists at {symlink_dir} - skipping sql output"
)
return

rows = []
Expand All @@ -221,16 +243,21 @@ def sql(self, args: Namespace) -> None:
row_clientpath = "unknown"
if args.clientpath:
# zarr_path is relative URL from .zarr /to/file/
zarr_path = str(row_path).replace(args.symlink_target, '')
zarr_path = str(row_path).replace(args.symlink_target, "")
row_clientpath = f"{args.clientpath}{zarr_path}/{row_name}"

# remove common path to shorten
row_path = str(row_path).replace(f"{symlink_path.parent}", "")
row_path = str(row_path).replace(f"{symlink_path.parent}", "") # type: ignore # noqa
if str(row_path).startswith("/"):
row_path = str(row_path)[1:] # remove "/" from start
# remove "/" from start
row_path = str(row_path)[1:] # type: ignore
row_full_path = f"{prefix}{self.suffix}/{row_path}"
# pick the first .zattrs file we find, then update to ome.xml if we find it
if setid_target is None and row_name == ".zattrs" or row_name == "METADATA.ome.xml":
if (
setid_target is None
and row_name == ".zattrs"
or row_name == "METADATA.ome.xml"
):
setid_target = [row_full_path, row_name]
rows.append(
ROW.format(
Expand All @@ -241,10 +268,13 @@ def sql(self, args: Namespace) -> None:
)
)

# Add a command to update the Pixels table with path/name using old Fileset ID *before* new Fileset is created
fpath = setid_target[0]
fname = setid_target[1]
self.ctx.out(f"UPDATE pixels SET name = '{fname}', path = '{fpath}' where image in (select id from Image where fileset = {args.fileset_id});")
# Add a command to update the Pixels table with
# path/name using old Fileset ID *before* new Fileset is created
fpath = setid_target[0] # type: ignore
fname = setid_target[1] # type: ignore
self.ctx.out(
f"UPDATE pixels SET name = '{fname}', path = '{fpath}' where image in (select id from Image where fileset = {args.fileset_id});" # noqa
)

self.ctx.out(
TEMPLATE.format(
Expand Down Expand Up @@ -274,7 +304,7 @@ def symlink(self, args: Namespace) -> None:
if args.bfoptions:
self.write_bfoptions(args.symlink_repo, prefix, args.symlink_target)

def get_prefix(self, args):
def get_prefix(self, args): # type: ignore

conn = self.ctx.conn(args) # noqa
q = conn.sf.getQueryService()
Expand All @@ -296,36 +326,33 @@ def get_prefix(self, args):

return prefix

def get_symlink_dir(self, symlink_repo, prefix):
def get_symlink_dir(self, symlink_repo, prefix): # type: ignore
prefix_dir = os.path.join(symlink_repo, prefix)
self.ctx.err(f"Checking for prefix_dir {prefix_dir}")
if not os.path.exists(prefix_dir):
self.ctx.die(402, f"Fileset dir does not exist: {prefix_dir}")
symlink_dir = f"{prefix_dir}{self.suffix}"
return symlink_dir

def write_bfoptions(self, managed_repo, fsprefix, symlink_target):
def write_bfoptions(self, managed_repo, fsprefix, symlink_target): # type: ignore # noqa
file_path = Path(symlink_target)
mkngff_dir = self.get_symlink_dir(managed_repo, fsprefix)
# os.makedirs(mkngff_dir, exist_ok=True)
zarr_path = os.path.join(mkngff_dir, file_path.name)
bfoptions_path = f"{zarr_path}.bfoptions"
self.ctx.err("write bfoptions to: %s" % bfoptions_path)
with open(bfoptions_path, "w") as f:
f.writelines(["omezarr.list_pixels=false",
"\nomezarr.quick_read=true"])
f.writelines(["omezarr.list_pixels=false", "\nomezarr.quick_read=true"])

def create_symlink(self, symlink_repo, prefix, symlink_target):
def create_symlink(self, symlink_repo, prefix, symlink_target): # type: ignore # noqa
symlink_path = Path(symlink_target)
symlink_dir = self.get_symlink_dir(symlink_repo, prefix)
self.ctx.err(f"Creating dir at {symlink_dir}")
os.makedirs(symlink_dir, exist_ok=True)

symlink_source = os.path.join(symlink_dir, symlink_path.name)
target_is_directory = os.path.isdir(symlink_target)
self.ctx.err(
f"Creating symlink {symlink_source} -> {symlink_target}"
)
self.ctx.err(f"Creating symlink {symlink_source} -> {symlink_target}")
# ignore if symlink exists
if not os.path.exists(symlink_source):
os.symlink(symlink_target, symlink_source, target_is_directory)
Expand Down
4 changes: 2 additions & 2 deletions test/integration/clitest/test_mkngff.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ def test_mkngff(self, capfd): # type: ignore
oid = self.create_object(object_type, name=f"{name}")
obj_arg = f"{object_type}:{oid}"
self.args += [obj_arg]
out = self.rdf(capfd)
assert out
# out = self.rdf(capfd)
# assert out