Skip to content

Conversation

@BrianWhitneyAI
Copy link
Contributor

@BrianWhitneyAI BrianWhitneyAI commented Dec 3, 2025

Description

The purpose of this PR is to improve our plugin selection. It aims to resolve bioio-devs/bioio-imageio#29 , bioio-devs/bioio-bioformats#45 and #161.

We have increasingly become aware that users like to have a lot of plugins installed at the same time. The priority of usage of a readers that support the same file (such as our tiff suites and imageio/bioformats catch-alls) didn't have an easy way for users to control what was used for their files other than specific reader definition. This PR allows for a priority list.

There was some hidden nuance around the plugin_feasibility_report (see #) The list of extensions is actually a approved list by bioio, the reader itself can support more file types (and often will). At runtime BioImage will only read files with the specific instruction. plugin_feasibility_report is not bound by extension and will try all readers regardless. This shows things like bioio-imageio supporting tiff images. This is intended but not explained. This pr adds a warning to describe the case.

The use case for this is if you have a file with a strange or new ext. you want to see if any of the readers can parse it. you use the plugin_feasibility_report to assess the file and see that bioio-bioformats can read it! you can then override the extension restriction by passing the the bioio-bioformats reader directly.

Description of Changes

  1. Adds in the plugin_priority parameter allowing users to specify a reader priority schema
  2. Adds tests to support plugin_priority
  3. Adds in docs / warning about plugin feasibility to describe "ext not present but supported" file case

Copy link
Contributor

@kmitcham kmitcham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An explicitly defined default order would improve the clarity of behavior.

extension against the known plugins.
- For each matching plugin, it tries to instantiate a reader and checks
if it supports the image.
- If multiple plugins match, optional ``plugin_priority`` takes precedence.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an explicit definition of what happens with multiple matches, but plugin_priority is not set? I think we want that, even if the defined order is the first plug alphabetically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of an order but alphabetical has some specific issues. one being that we would be reccomending bioio-bioformats as our primary reader, which is not what we want to do. A thought that came out of a conversation between kevin and I was that we sort default plugin priority by the length of the extension list. This would move more specific readers to the top and more general readers to the bottom. Then if a user wants something specific they define a priority list or a single reader. This could have some pitfalls one I can think of is that ome-tiff has length 4 and tifffile has length 3. @toloudis what are your thoughts about a default order?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this priority order?

  • Check extensions in order of length (e.g., if plugins support .c, .b.c, and .a.b.c, then ingesting file.a.b.c will first look for plugins supporting .a.b.c, then .b.c)
    • Among plugins that support the same extension, choose the one that supports the fewest extensions total.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im working on an implementation now for bioio-tiff-glob, bioio-ome-tiff, bioio-tifffile,bioio-bioformats our priority list would be

Extension: .tiff
----------------
[0] entrypoint: bioio-tiff-glob
     Reader: bioio_tiff_glob.reader.Reader
     Supported extensions: ['.tif', '.tiff']

[1] entrypoint: bioio-ome-tiff
     Reader: bioio_ome_tiff.reader.Reader
     Supported extensions: ['.ome.tiff', '.tiff', 'ome.tif', '.tif']

[2] entrypoint: bioio-tifffile
     Reader: bioio_tifffile.reader.Reader
     Supported extensions: ['tif', 'tiff', 'lsm']

[3] entrypoint: bioio-bioformats
     Reader: bioio_bioformats.reader.Reader
     Supported extensions: ['.1sc', '.2fl', '.acff', '.afi', '.afm', '.aim', '.al3d', '.am', '.amiramesh', '.apl', '.arf', '.avi', '.bin', '.bip', '.bmp', '.btf', '.c01', '.cfg', '.ch5', '.cif', '.cr2', '.crw', '.csv', '.cxd', '.czi', '.dat', '.dcm', '.dib', '.dm2', '.dm3', '.dm4', '.dti', '.dv', '.eps ', '.exp', '.fdf', '.fff', '.ffr', '.fits', '.flex', '.fli', '.frm', '.gel', '.gif', '.grey', '.hdf', '.hdr', '.hed', '.his', '.htd', '.html', '.hx', '.i2i', '.ics', '.ids', '.im3', '.img', '.ims', '.inr', '.ipl', '.ipm', '.ipw', '.jp2', '.jpg', '.jpk', '.jpx', '.l2d', '.labels', '.lei', '.lif', '.liff', '.lim', '.lms', '.lsm', '.mdb', '.mnc', '.mng', '.mod', '.mov', '.mrc', '.mrw', '.msr', '.mtb', '.mvd2', '.naf', '.nd', '.nd2', '.ndpi', '.ndpis', '.nef', '.nhdr', '.nii', '.nii.gz', '.nrrd', '.obf', '.obsep', '.oib', '.oif', '.oir', '.ome', '.ome.btf', '.ome.tf2', '.ome.tf8', '.ome.tif', '.ome.tiff', '.ome.xml', '.par', '.pbm', '.pcoraw', '.pcx', '.pds', '.pgm', '.pic', '.pict', '.png', '.pnl', '.ppm', '.pr3', '.psd', '.qptiff', '.r3d', '.raw', '.rcpnl', '.rec', '.scn', '.sdt', '.seq', '.sif', '.sld', '.sm2', '.sm3', '.spc', '.spe', '.spi', '.stk', '.stp', '.svs', '.sxm', '.tf2', '.tf8', '.tfr', '.tga', '.tif', '.tiff', '.tnb', '.top', '.txt', '.v', '.vms', '.vsi', '.vws', '.wat', '.wlz', '.xdce', '.xml', '.xqd', '.xqf', '.xv', '.xys', '.zfp', '.zfr', '.zvi']

This would essentially say the more specific a plugin you install the higher in the priority list ill be. ome-tiff-glob is extremely specific and has 2 families of support .tiff and .tif. bioio-ome-tifff also has 2 families but a larger extension list bioio-tifffile has 3 families and bioio-bioformats has a ton.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So is the intention to have a different priority list for every extension? That seems like a lot of effort for little reward (given the number of relevant extensions)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No we determine priority from ext list for each plugin based on (at bioio level):

  • Fewer extension families first — Plugins that support fewer groups of suffix-related extensions (e.g., .ome.tiff + .tiff is one family) are considered more specific and are ranked higher.
  • If tied, fewer raw extensions first — A plugin advertising fewer total extensions in its get_supported_extensions() list is treated as more focused and ranked higher.
  • If still tied, alphabetical by plugin name — A stable, deterministic tie-breaker.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the above description, the index of the plugin is its priority (0 being highest)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The priority approach of @pgarrison resonates with how I like to think about the various plugins, especially where I want the (presumed) most specific plugin to be prioritized first, and seeing how @BrianWhitneyAI laid it out makes me more certain that its both logical and easily understood with minimal documentation (which, right now is actually quite hard). I've followed y'alls discussions for a while, and while I'm unhappy about the current prioritization (i.e. time-of-install) nothing else has stood out as a compelling alternative until this.

I think this proposed prioritization logic would cover all edge cases that I keep running in to, but it is nice that there still is this proposed API for a priority override. It will make troubleshooting a set of reader behaviors more quickly than just trying to pass the correct reader function.

bioio/plugins.py Outdated
Prioritized plugin list.
"""
if not plugin_priority:
return plugins
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we do a default sort here? just to make it deterministic, and not based on whatever drives it now?

Copy link
Contributor

@pgarrison pgarrison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I like this approach

extension against the known plugins.
- For each matching plugin, it tries to instantiate a reader and checks
if it supports the image.
- If multiple plugins match, optional ``plugin_priority`` takes precedence.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this priority order?

  • Check extensions in order of length (e.g., if plugins support .c, .b.c, and .a.b.c, then ingesting file.a.b.c will first look for plugins supporting .a.b.c, then .b.c)
    • Among plugins that support the same extension, choose the one that supports the fewest extensions total.

Comment on lines 89 to 93
monkeypatch.setattr(
bio_image,
"get_plugins",
lambda use_cache: fake_plugins_by_ext,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we define a default plugin order more explicitly, maybe this test can rely on that instead of modifying get_plugins

Co-authored-by: Philip Garrison <pgarrison@users.noreply.github.com>
@toloudis
Copy link
Contributor

toloudis commented Dec 4, 2025

I have a few thoughts I'd like to add.

  1. It's good for users to provide a reader= arg to BioImage ctor. This is my favorite way to resolve ambiguities and I would want our documentation to advocate for doing things this way.
    1a. In this PR I would advocate to extend the reader parameter to allow a list of Reader classes to be passed in optionally, rather than adding a new param for plugin_priority.
  2. If the feasibility report behaves differently than what the BioImage constructor does, then we should fix that so that things are consistent/predictable. (It needs to at least be clear what users should expect)
  3. We need to make it really loud and clear in our docs about the current, existing precedence rules. We could also give users hints about how to uninstall plugins and reinstall in the order they want. If it turns out that the date stamp thing is actually unreliable, then we have an actual bug and we really do need to change the default precedence rules.

@BrianWhitneyAI BrianWhitneyAI marked this pull request as draft December 4, 2025 23:53
image: biob.types.ImageLike,
fs_kwargs: Dict[str, Any] = {},
use_plugin_cache: bool = False,
plugin_priority: Optional[Sequence[Type[biob.reader.Reader]]] = None,
Copy link
Contributor

@TimMonko TimMonko Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a thought, how difficult would it be to accept the names of the entrypoints here, rather than the Reader? That way the sequence could be constructed without having to do imports. It's just, simpler perhaps? I suppose the same would be nice if I could pass the entry point name to the reader parameter as well, maybe I should make a new issue? Using the entrypoint name would be much easier for colleagues that are less familiar with finding python objects

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be hesitant to allow a string parameter here. Importing the Readers directly allows us to tighten our typing and doesn't require a users knowledge of entrypoint logic. Im also not sure we want to point users towards entrypoint logic from a documentation standpoint as we have pushed so hard for the plugin reader structure.

@TimMonko
Copy link
Contributor

TimMonko commented Dec 7, 2025

I already create my own preferred ordering system as a workaround so this all makes sense to me as something that should be supported.

I think I would be able to remove near all of it. The only value of this code that I would keep is having a configurable global setting override, but that would just become this new plugin priority list instead, so still using the new API. I mean maybe its worth looking at briefly just to make sure I haven't created something kinda useful? 🫣

https://github.com/ndev-kit/ndevio/blob/841d84ef9983036ca25d7fb48874c02c79a1b781/src/ndevio/_plugin_manager.py#L226-L261

@pgarrison
Copy link
Contributor

pgarrison commented Dec 8, 2025

1a. In this PR I would advocate to extend the reader parameter to allow a list of Reader classes to be passed in optionally, rather than adding a new param for plugin_priority.

This makes sense to me; fewer paramaters to learn and the same functionality.

  1. We need to make it really loud and clear in our docs about the current, existing precedence rules. We could also give users hints about how to uninstall plugins and reinstall in the order they want. If it turns out that the date stamp thing is actually unreliable, then we have an actual bug and we really do need to change the default precedence rules.

@toloudis I don't think "reinstall in the priority order you want" is a great user experience. I haven't encountered any other library where install order is part of the API. For projects where you install from a lockfile, controlling install order is nearly impossible. And on larger projects it's complicated to keep plugin install order consistent across developers or machines. I'm surprised we haven't seen more "doesn't happen on my machine" issues related to this.

@codecov
Copy link

codecov bot commented Dec 8, 2025

Codecov Report

❌ Patch coverage is 94.85531% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.40%. Comparing base (9dc5c2c) to head (b333927).
⚠️ Report is 20 commits behind head on main.

Files with missing lines Patch % Lines
bioio/plugins.py 85.48% 9 Missing ⚠️
bioio/bio_image.py 83.33% 4 Missing ⚠️
bioio/tests/helpers/mock_reader.py 96.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #162      +/-   ##
==========================================
+ Coverage   83.14%   85.40%   +2.25%     
==========================================
  Files          11       13       +2     
  Lines         724      911     +187     
==========================================
+ Hits          602      778     +176     
- Misses        122      133      +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@BrianWhitneyAI
Copy link
Contributor Author

I added df9a7bd to show a possible priority policy. We can revert it if/when we decide a different route

@TimMonko
Copy link
Contributor

TimMonko commented Dec 8, 2025

  1. We need to make it really loud and clear in our docs about the current, existing precedence rules. We could also give users hints about how to uninstall plugins and reinstall in the order they want. If it turns out that the date stamp thing is actually unreliable, then we have an actual bug and we really do need to change the default precedence rules.

@toloudis I don't think "reinstall in the priority order you want" is a great user experience. I haven't encountered any other library where install order is part of the API. For projects where you install from a lockfile, controlling install order is nearly impossible. And on larger projects it's complicated to keep plugin install order consistent across developers or machines. I'm surprised we haven't seen more "doesn't happen on my machine" issues related to this.

So, I think this is the cause of how I even identified bioio-devs/bioio-imageio#29

I haven't had time to fully debug, but I'm pretty sure the behavior is different between pip and uv pip with dependency resolution order. My impression is that a dependencies list of ['bioio-ome-tiff', 'bioio-tifffile', 'bioio-imageio'] would resolve differently time wise, namely:
With pip, it installs in list order..., so ['bioio-ome-tiff', 'bioio-tifffile', 'bioio-imageio']
But with uv pip, I'm fairly certain it ends up in alphabetical order when I looked at the plugins list (can't remember the name of the command of the top of my head) ['bioio-imageio', 'bioio-ome-tiff', 'bioio-tifffile'] and that's why I was suddenly getting confused by it reading with bioio-imageio (though, the issue stands on its own as confusing because of differences between "approved list" vs "actually can be read by") when previous behavior for the same file was bioio-tifffile with those dependencies.

I hadn't made an issue because maybe I was going crazy, or maybe you had changed resolution order, but I did want to show where I ran into this.
So even if someone wants to reproduce an environment, it might depend on the install tool (including the as-mentioned lockfiles which I've also observed different behavior from)

@BrianWhitneyAI
Copy link
Contributor Author

BrianWhitneyAI commented Dec 8, 2025

I haven't had time to fully debug, but I'm pretty sure the behavior is different between uv and uv pip with dependency resolution order. My impression is that a dependencies list of ['bioio-ome-tiff', 'bioio-tifffile', 'bioio-imageio'] would resolve differently time wise, namely: With pip, it installs in list order..., so ['bioio-ome-tiff', 'bioio-tifffile', 'bioio-imageio'] But with uv pip, I'm fairly certain it ends up in alphabetical order when I looked at the plugins list (can't remember the name of the command of the top of my head) ['bioio-imageio', 'bioio-ome-tiff', 'bioio-tifffile'] and that's why I was suddenly getting confused by it reading with bioio-imageio (though, the issue stands on its own as confusing because of differences between "approved list" vs "actually can be read by") when previous behavior for the same file was bioio-tifffile with those dependencies.

I have some suspicions about version management as well. Particularly around envs sharing installed package versions.

@toloudis
Copy link
Contributor

toloudis commented Dec 9, 2025

@toloudis I don't think "reinstall in the priority order you want" is a great user experience. I haven't encountered any other library where install order is part of the API. For projects where you install from a lockfile, controlling install order is nearly impossible. And on larger projects it's complicated to keep plugin install order consistent across developers or machines. I'm surprised we haven't seen more "doesn't happen on my machine" issues related to this.

I understand. I am not in love with "install order", and realize how silly it sounded to document how to install things in a certain order. In a world where users can write their own plugins which report supported file extensions, ties will have to be broken somehow. (e.g. There can be N different plugins installed, all claiming to support ".tiff") The feasibility report thing is a nice way to diagnose (assuming it works predictably and consistently).

Anyway, I don't want to block progress on a better way to determine plugin precedence.

It sounds like install order is truly unreliable due to differences in the sequence of processing pyproject.toml or lock files.

Copy link
Contributor

@kmitcham kmitcham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple more doc nits, but looks good.

Copy link
Contributor

@TimMonko TimMonko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted time to do a more full review, and I think the biggest opinion I have is in https://github.com/bioio-devs/bioio/pull/162/files#r2595957308 about how to think about the code pathways and trying to avoid confusion.

I did have a go at testing out how this would change things for my design (i.e. my own ordering of plugin priority to overcome the current issues) and really like it! ndev-kit/ndevio#42. I especially like that I can pass reader=[Reader] with just one, and it will still use the fallbacks of bioio. This way I can emit a warning to users that their intended reader isn't working, but if they expect certain behavior they can easily "choose" a reader. This is just a better experience for someone working in napari.

If the proposed deterministic ordering is used (fewer suffixes prioritized as more specific) I will be very happy and overall these changes would be a big improvement to my experience with bioio, and I hope for others.

Thanks for the great work and continued tuning to get, what I think, is a key and fantastic feature. If it goes it as is, that will also work for me :)


# Determine reader class based on available plugins
# Determine plugin with priority
plugin_priority: Optional[Sequence[Type[biob.reader.Reader]]] = None
Copy link
Contributor

@TimMonko TimMonko Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll offer my biggest opinion here. I think this discussion shows the challenge of condensing these behaviors to just the reader arg.

First, I find that type-dependent behavior, as here with reader=Reader and reader=[Reader], taking different code paths to be very confusing and requires clear documentation as to why. From my perspective passing a list of just 1 item should have the same behavior as passing that item outside a list.

oh I thought that if a user passed a list of readers, then we should only try those readers and then stop. that seems more predictable from an api standpoint but I can see why you might want to do it the other way too.

Second, I think @toloudis points out that perhaps this makes even more room for separating this functionality into two different args. With this in mind I would propose for BioImage:

  1. reader: Reader | Sequence[Reader] | None = None should try only those plugins if not None. This would be an extension of current API and result in ordered passing of each Reader, only.
  2. plugin_priority: Reader | Sequence[Reader] | None = None should try these plugins "at the top of the list" of bioio's ordering, otherwise fallback to bioio's ordering, with the warning emitted as now during fallback
  3. If reader and plugin_priority are both not None, then emit a warning to the user, but use the reader pathway

This allows clear separation of the pathways and intent of each.

image: biob.types.ImageLike,
reader: biob.reader.Reader,
reader: Optional[
Union[Type[biob.reader.Reader], Sequence[Type[biob.reader.Reader]]]
Copy link
Contributor

@toloudis toloudis Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe at this layer you could simplify by always passing in a sequence of Reader (or None)

image: biob.types.ImageLike,
reader: Optional[Type[biob.reader.Reader]] = None,
reader: Optional[
Union[Type[biob.reader.Reader], Sequence[Type[biob.reader.Reader]]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inside this function, could convert single reader to [reader] as early as possible and then treat it as a sequence for the get_reader function call.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved in 3d3f727

def test_bioimage_attempts_s3_read_with_anon_attr(
sample_text_file: pathlib.Path, dummy_plugin: str
sample_text_file: pathlib.Path,
plugin_factory: Callable[[Iterable[TestPluginSpec]], list[EntryPoint]],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be naive about how to write Python tests, but the code looks weird having plugin_factory be an input argument to all the functions. A type definition to shorten Callable[[Iterable[TestWriterSpec]], list[EntryPoint]] would probably be nice for readability. Maybe name it as plugin_factory: PluginFactoryFixture ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in 3d3f727 Type definition doesn't quite work without some aliasing so I added some protocol support should work the same way

),
],
["list_reader_plugin_a", "list_reader_plugin_b"],
0,
Copy link
Contributor

@toloudis toloudis Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make one where the expected winner_idx is not zero. (add a plugin spec that has the wrong extension or something?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added two new cases, removing the test below this one and moving its case into the params see 3d3f727

# Check if package name is in the output
assert dummy_plugin in output
# Assert: plugin name appears in dump
assert "dummy_plugin" in output
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a good enough test of dump_plugins? what else could you assert here?

Copy link
Contributor Author

@BrianWhitneyAI BrianWhitneyAI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test assertions are pre-existing. We could add some specific assertions about the wording but Im not sure what else we would want.

Copy link
Contributor

@toloudis toloudis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, one small thing that should be easy to update; see if you agree.

self._plugin: Optional[PluginEntry] = None

# Normalize Single Reader
if reader is not None and isinstance(reader, type):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this type check could be a little bit stronger

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We go on to do another check in _get_reader so I think its ok.

        if not readers or not all(
            isinstance(r, type) and issubclass(r, biob.reader.Reader) for r in readers
        ):
            raise TypeError(
                "BioImage(reader=...) must be a Reader subclass, "
                "a non-empty sequence of Reader subclasses, or None."
            )

@BrianWhitneyAI BrianWhitneyAI merged commit 808e5d5 into main Dec 22, 2025
18 checks passed
@BrianWhitneyAI BrianWhitneyAI deleted the feature/plugin-priority branch December 22, 2025 18:59
TimMonko added a commit to ndev-kit/ndevio that referenced this pull request Dec 24, 2025
# References and relevant issues

Depends on bioio-devs/bioio#162 / bioio v3.2.0

# Description

1. Remove bespoke prioritization system
2. Just detect installed plugins and offer suggestions to install known
bioio plugins if the file can't be read by the currently installed
3. Depends on bioio's new deterministic orderering (fewest suffixes are
prioritized as more specific)
4. Changes default "preferred_reader" setting to None, and passes this
now as `reader=[Reader]` to allow fallback to bioio's ordering (though
this fallback is in nImage now)
5. updates extensions used by directly copying from bioio libraries
6. simplifies napari reader check to just pass forward with less checks,
expecting that our extensions check by napari will cover it
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Why does bioio-imageio read tiff files?

7 participants