openjournals / joss-reviews

Reviews for the Journal of Open Source Software
Creative Commons Zero v1.0 Universal
712 stars 38 forks source link

[REVIEW]: MSMetaEnhancer: A Python package for mass spectra metadata annotation #4494

Closed editorialbot closed 1 year ago

editorialbot commented 2 years ago

Submitting author: !--author-handle-->@hechth<!--end-author-handle-- (Helge Hecht) Repository: https://github.com/RECETOX/MSMetaEnhancer Branch with paper.md (empty if default branch): Version: 0.2.5 Editor: !--editor-->@csoneson<!--end-editor-- Reviewers: @marshallmcdonnell, @chryswoods Archive: 10.5281/zenodo.7211726

Status

status

Status badge code:

HTML: <a href="https://joss.theoj.org/papers/3f13cf143b693763478efb53fe275b27"><img src="https://joss.theoj.org/papers/3f13cf143b693763478efb53fe275b27/status.svg"></a>
Markdown: [![status](https://joss.theoj.org/papers/3f13cf143b693763478efb53fe275b27/status.svg)](https://joss.theoj.org/papers/3f13cf143b693763478efb53fe275b27)

Reviewers and authors:

Please avoid lengthy details of difficulties in the review thread. Instead, please create a new issue in the target repository and link to those issues (especially acceptance-blockers) by leaving comments in the review thread below. (For completists: if the target issue tracker is also on GitHub, linking the review thread in the issue or vice versa will create corresponding breadcrumb trails in the link target.)

Reviewer instructions & questions

@marshallmcdonnell & @chryswoods, your review will be checklist based. Each of you will have a separate checklist that you should update when carrying out your review. First of all you need to run this command in a separate comment to create the checklist:

@editorialbot generate my checklist

The reviewer guidelines are available here: https://joss.readthedocs.io/en/latest/reviewer_guidelines.html. Any questions/concerns please let @csoneson know.

✨ Please start on your review when you are able, and be sure to complete your review in the next six weeks, at the very latest ✨

Checklists

πŸ“ Checklist for @chryswoods

πŸ“ Checklist for @marshallmcdonnell

editorialbot commented 2 years ago

Hello humans, I'm @editorialbot, a robot that can help you with some common editorial tasks.

For a list of things I can do to help you, just type:

@editorialbot commands

For example, to regenerate the paper pdf after making changes in the paper's md or bib files, type:

@editorialbot generate pdf
editorialbot commented 2 years ago
Software report:

github.com/AlDanial/cloc v 1.88  T=0.05 s (1274.1 files/s, 72889.2 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Python                          41            508            654           1289
TeX                              1             24              0            278
Markdown                         4             71              0            240
YAML                             8             22             12            188
reStructuredText                 6             53             92             61
DOS Batch                        1              8              1             26
make                             1              4              7              9
-------------------------------------------------------------------------------
SUM:                            62            690            766           2091
-------------------------------------------------------------------------------

gitinspector failed to run statistical information for the repository
editorialbot commented 2 years ago

Wordcount for paper.md is 1199

editorialbot commented 2 years ago
Reference check summary (note 'MISSING' DOIs are suggestions that need verification):

OK DOIs

- None

MISSING DOIs

- None

INVALID DOIs

- 10.1101/2021.02.28.433248 is INVALID
- 10.21105/joss.02411 is INVALID
- 10.1093/bioinformatics/btq476 is INVALID
- 10.1300/j115v21n01_04 is INVALID
- 10.1093/nar/gkaa971 is INVALID
- 10.1093/bioinformatics/btn307 is INVALID
- 10.1093/nar/gky379 is INVALID
- 10.1038/s41592-018-0046-7 is INVALID
- 10.1186/s13321-021-00515-1 is INVALID
- 10.5281/zenodo.6035335 is INVALID
- 10.1093/nar/gkab1062 is INVALID
- 10.1186/1471-2105-11-5 is INVALID
- 10.3390/metabo8010016 is INVALID
- 10.3897/rio.8.e83031 is INVALID
- 10.3389/fpubh.2021.622558 is INVALID
- 10.1007/s13361-016-1589-4 is INVALID
- 10.1016/S1044-0305(98)00159-7 is INVALID
- 10.1002/jms.3131 is INVALID
editorialbot commented 2 years ago

:point_right::page_facing_up: Download article proof :page_facing_up: View article proof on GitHub :page_facing_up: :point_left:

csoneson commented 2 years ago

πŸ‘‹πŸΌ @hechth, @marshallmcdonnell, @chryswoods - this is the review thread for the submission. All of our communications will happen here from now on.

Please check the post at the top of the issue for instructions on how to generate your own review checklist. As you go over the submission, please check any items that you feel have been satisfied. There are also links to the JOSS reviewer guidelines.

The JOSS review is different from most other journals. Our goal is to work with the authors to help them meet our criteria instead of merely passing judgment on the submission. As such, the reviewers are encouraged to submit issues directly in the software repository. If you do so, please mention this thread so that a link is created (and I can keep an eye on what is happening). Please also feel free to comment and ask questions in this thread. It is often easier to post comments/questions/suggestions as you come across them instead of waiting until you've reviewed the entire package.

Please feel free to ping me (@csoneson) if you have any questions or concerns. Thanks!

hechth commented 2 years ago

@csoneson Is there maybe some issue with the DOI checker? We had a look at the DOIs and they actually seem fine.

csoneson commented 2 years ago

@editorialbot check references

editorialbot commented 2 years ago
Reference check summary (note 'MISSING' DOIs are suggestions that need verification):

OK DOIs

- None

MISSING DOIs

- None

INVALID DOIs

- 10.1101/2021.02.28.433248 is INVALID
- 10.21105/joss.02411 is INVALID
- 10.1093/bioinformatics/btq476 is INVALID
- 10.1300/j115v21n01_04 is INVALID
- 10.1093/nar/gkaa971 is INVALID
- 10.1093/bioinformatics/btn307 is INVALID
- 10.1093/nar/gky379 is INVALID
- 10.1038/s41592-018-0046-7 is INVALID
- 10.1186/s13321-021-00515-1 is INVALID
- 10.5281/zenodo.6035335 is INVALID
- 10.1093/nar/gkab1062 is INVALID
- 10.1186/1471-2105-11-5 is INVALID
- 10.3390/metabo8010016 is INVALID
- 10.3897/rio.8.e83031 is INVALID
- 10.3389/fpubh.2021.622558 is INVALID
- 10.1007/s13361-016-1589-4 is INVALID
- 10.1016/S1044-0305(98)00159-7 is INVALID
- 10.1002/jms.3131 is INVALID
csoneson commented 2 years ago

Hm, not sure what is going on here. @openjournals/dev - any idea? The DOIs were considered valid in the pre-review issue.

xuanxu commented 2 years ago

@editorialbot check references

Maybe the doi.org website was down? let's try again

editorialbot commented 2 years ago
Reference check summary (note 'MISSING' DOIs are suggestions that need verification):

OK DOIs

- 10.1101/2021.02.28.433248 is OK
- 10.21105/joss.02411 is OK
- 10.1093/bioinformatics/btq476 is OK
- 10.1300/j115v21n01_04 is OK
- 10.1093/nar/gkaa971 is OK
- 10.1093/bioinformatics/btn307 is OK
- 10.1093/nar/gky379 is OK
- 10.1038/s41592-018-0046-7 is OK
- 10.1186/s13321-021-00515-1 is OK
- 10.5281/zenodo.6035335 is OK
- 10.1093/nar/gkab1062 is OK
- 10.1186/1471-2105-11-5 is OK
- 10.3390/metabo8010016 is OK
- 10.3897/rio.8.e83031 is OK
- 10.3389/fpubh.2021.622558 is OK
- 10.1007/s13361-016-1589-4 is OK
- 10.1016/S1044-0305(98)00159-7 is OK
- 10.1002/jms.3131 is OK

MISSING DOIs

- None

INVALID DOIs

- None
xuanxu commented 2 years ago

Β―\_(ツ)_/Β―

csoneson commented 2 years ago

πŸ™‚ Thanks!

chryswoods commented 2 years ago

Review checklist for @chryswoods

Conflict of interest

Code of Conduct

General checks

Functionality

Documentation

Software paper

chryswoods commented 2 years ago

Just to say that I am going through the review. Have got the software installed and now running the tests. I've seen a test failure that I have reported here.

csoneson commented 2 years ago

Thanks for the update @chryswoods!

@marshallmcdonnell - just wanted to check in on your review; please let me know if you have any questions!

Thanks!

marshallmcdonnell commented 2 years ago

Hi @csoneson!

Apologies for delay, looked over repo but will begin review now.

Thanks!

marshallmcdonnell commented 2 years ago

Review checklist for @marshallmcdonnell

Conflict of interest

Code of Conduct

General checks

Functionality

Documentation

Software paper

marshallmcdonnell commented 2 years ago

@hechth, I'm excited about your software package, big fan of tools that help add and standardize metadata! Clean code base, was very readable. Good intuitive design for the Python API. Also tried out the UMSA Galaxy tool, worked great!

I honestly just have non-mandatory suggestions. No major issues from me so I don't see any issues publishing in JOSS.

Suggestions

Tests ran as expected. Installation via conda was as expected. Able to run the example in README. USMA Galaxy install ran as expected.

Let me know if you have questions about these issues and happy to engage in a discussion.

chryswoods commented 2 years ago

@hechth - I agree with @marshallmcdonnell that this is a great tool. Very clean code.

I agree with the suggestion of updating the presentation of the documentation on the readthedocs website. It can help to attract new users if they can see a general introduction plus some examples first. The API docs are useful, but tend to be something that someone will read after they have used the tool for longer, and progressed beyond just basic usage. In my experience, you can never have enough "basic usage" tutorials ;-).

I am stuck with my review by the test failure and also a runtime error when running the example. I've reported these to the repo.

I did struggle to install the software from conda. This was mostly because of unresolvable dependencies, even in a vanilla miniconda environment. I ended up getting it working by using a vanilla minimamba on Linux.

I agree with @marshallmcdonnell it may make packaging easier if you unified the environment and package management. I noticed that your requirements.txt has lots of pinning of package versions, while your conda recipe was relatively unpinned. I recommend removing the pins from requirements.txt or making it match up more with what is in the conda recipe.

csoneson commented 2 years ago

πŸ‘‹πŸ» Just wanted to check in how things are going here. It looks to me like things are moving in order to address the test failue in the open issues above πŸ‘πŸ» - @hechth, feel free to post here if there are questions related to the other reviewer comments, or when you are ready for them to take a second look. Thanks!

hechth commented 2 years ago

@chryswoods @csoneson and @marshallmcdonnell Thanks for the great review and handling of this submission.

I think we will still have a look at the package structure and dependence management system as these things are quite important for us as well to get right!

csoneson commented 2 years ago

πŸ‘‹πŸ» @hechth - just wanted to check in to see where things are at (no stress, just to have a feeling for when the reviewers may expect a new version to look at, and to make sure that the submission remains active πŸ™‚)

csoneson commented 2 years ago

Ping @hechth

πŸ‘‹πŸ» @hechth - just wanted to check in to see where things are at (no stress, just to have a feeling for when the reviewers may expect a new version to look at, and to make sure that the submission remains active πŸ™‚)

hechth commented 2 years ago

@csoneson Sorry for the delay and absence - I think we fixed all issues that were mentioned in the review, I am now testing the newly deployed version on our Galaxy instance to make sure everything runs also smoothly in production. I will make a release on Zenodo with that version afterwards so we can continue with the publication process :).

Thank you very much for your time and patience.

hechth commented 2 years ago

@chryswoods and @marshallmcdonnell It would be great if you could have a final look at the software and then finalize the checklists. Thank you very much!

hechth commented 2 years ago

@csoneson @chryswoods and @marshallmcdonnell - Version 0.2.4 is released and also available on Galaxy. It contains a simplified setup, and the circuit breaker pattern for aiohttp.

Please let me know whether the paper can be considered as accepted so that I can create the repository on Zenodo :).

marshallmcdonnell commented 2 years ago

@hechth Thanks for addressing all of my reviewer comments! Much appreciated and great work!

@csoneson I am happy and in my opinion, the submission is ready! :+1:

chryswoods commented 2 years ago

Thanks - I also really appreciate all the work you have done. I am though still struggling to install the software following the instructions on your website. I have tried on a variety of platforms. For example, it doesn't install on Linux using a new, clean installation of the latest version of miniconda. Here's all the output;

(base) [opc@metawards ~]$ conda create --name MSMetaEnhancer python=3.9
Collecting package metadata (current_repodata.json): done
Solving environment: done

## Package Plan ##

  environment location: /home/opc/miniconda3/envs/MSMetaEnhancer

  added / updated specs:
    - python=3.9

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    _libgcc_mutex-0.1          |      conda_forge           3 KB  conda-forge
    _openmp_mutex-4.5          |            2_gnu          23 KB  conda-forge
    bzip2-1.0.8                |       h7f98852_4         484 KB  conda-forge
    ca-certificates-2022.6.15.2|       ha878542_0         150 KB  conda-forge
    ld_impl_linux-64-2.36.1    |       hea4e1c9_2         667 KB  conda-forge
    libffi-3.4.2               |       h7f98852_5          57 KB  conda-forge
    libgcc-ng-12.1.0           |      h8d9b700_16         940 KB  conda-forge
    libgomp-12.1.0             |      h8d9b700_16         459 KB  conda-forge
    libnsl-2.0.0               |       h7f98852_0          31 KB  conda-forge
    libsqlite-3.39.3           |       h753d276_0         789 KB  conda-forge
    libuuid-2.32.1             |    h7f98852_1000          28 KB  conda-forge
    libzlib-1.2.12             |       h166bdaf_3          65 KB  conda-forge
    ncurses-6.3                |       h27087fc_1        1002 KB  conda-forge
    openssl-3.0.5              |       h166bdaf_2         2.8 MB  conda-forge
    pip-22.2.2                 |     pyhd8ed1ab_0         1.5 MB  conda-forge
    python-3.9.13              |h2660328_0_cpython        26.7 MB  conda-forge
    readline-8.1.2             |       h0f457ee_0         291 KB  conda-forge
    setuptools-65.3.0          |     pyhd8ed1ab_1         782 KB  conda-forge
    sqlite-3.39.3              |       h4ff8645_0         789 KB  conda-forge
    tk-8.6.12                  |       h27826a3_0         3.3 MB  conda-forge
    tzdata-2022c               |       h191b570_0         119 KB  conda-forge
    wheel-0.37.1               |     pyhd8ed1ab_0          31 KB  conda-forge
    xz-5.2.6                   |       h166bdaf_0         409 KB  conda-forge
    ------------------------------------------------------------
                                           Total:        41.2 MB

The following NEW packages will be INSTALLED:

  _libgcc_mutex      conda-forge/linux-64::_libgcc_mutex-0.1-conda_forge
  _openmp_mutex      conda-forge/linux-64::_openmp_mutex-4.5-2_gnu
  bzip2              conda-forge/linux-64::bzip2-1.0.8-h7f98852_4
  ca-certificates    conda-forge/linux-64::ca-certificates-2022.6.15.2-ha878542_0
  ld_impl_linux-64   conda-forge/linux-64::ld_impl_linux-64-2.36.1-hea4e1c9_2
  libffi             conda-forge/linux-64::libffi-3.4.2-h7f98852_5
  libgcc-ng          conda-forge/linux-64::libgcc-ng-12.1.0-h8d9b700_16
  libgomp            conda-forge/linux-64::libgomp-12.1.0-h8d9b700_16
  libnsl             conda-forge/linux-64::libnsl-2.0.0-h7f98852_0
  libsqlite          conda-forge/linux-64::libsqlite-3.39.3-h753d276_0
  libuuid            conda-forge/linux-64::libuuid-2.32.1-h7f98852_1000
  libzlib            conda-forge/linux-64::libzlib-1.2.12-h166bdaf_3
  ncurses            conda-forge/linux-64::ncurses-6.3-h27087fc_1
  openssl            conda-forge/linux-64::openssl-3.0.5-h166bdaf_2
  pip                conda-forge/noarch::pip-22.2.2-pyhd8ed1ab_0
  python             conda-forge/linux-64::python-3.9.13-h2660328_0_cpython
  readline           conda-forge/linux-64::readline-8.1.2-h0f457ee_0
  setuptools         conda-forge/noarch::setuptools-65.3.0-pyhd8ed1ab_1
  sqlite             conda-forge/linux-64::sqlite-3.39.3-h4ff8645_0
  tk                 conda-forge/linux-64::tk-8.6.12-h27826a3_0
  tzdata             conda-forge/noarch::tzdata-2022c-h191b570_0
  wheel              conda-forge/noarch::wheel-0.37.1-pyhd8ed1ab_0
  xz                 conda-forge/linux-64::xz-5.2.6-h166bdaf_0

Proceed ([y]/n)? y

Downloading and Extracting Packages
bzip2-1.0.8          | 484 KB    | ################################################################################################################# | 100% 
ca-certificates-2022 | 150 KB    | ################################################################################################################# | 100% 
setuptools-65.3.0    | 782 KB    | ################################################################################################################# | 100% 
python-3.9.13        | 26.7 MB   | ################################################################################################################# | 100% 
xz-5.2.6             | 409 KB    | ################################################################################################################# | 100% 
tzdata-2022c         | 119 KB    | ################################################################################################################# | 100% 
_openmp_mutex-4.5    | 23 KB     | ################################################################################################################# | 100% 
wheel-0.37.1         | 31 KB     | ################################################################################################################# | 100% 
_libgcc_mutex-0.1    | 3 KB      | ################################################################################################################# | 100% 
libgcc-ng-12.1.0     | 940 KB    | ################################################################################################################# | 100% 
libnsl-2.0.0         | 31 KB     | ################################################################################################################# | 100% 
libgomp-12.1.0       | 459 KB    | ################################################################################################################# | 100% 
readline-8.1.2       | 291 KB    | ################################################################################################################# | 100% 
openssl-3.0.5        | 2.8 MB    | ################################################################################################################# | 100% 
libffi-3.4.2         | 57 KB     | ################################################################################################################# | 100% 
libuuid-2.32.1       | 28 KB     | ################################################################################################################# | 100% 
ncurses-6.3          | 1002 KB   | ################################################################################################################# | 100% 
libzlib-1.2.12       | 65 KB     | ################################################################################################################# | 100% 
ld_impl_linux-64-2.3 | 667 KB    | ################################################################################################################# | 100% 
pip-22.2.2           | 1.5 MB    | ################################################################################################################# | 100% 
sqlite-3.39.3        | 789 KB    | ################################################################################################################# | 100% 
tk-8.6.12            | 3.3 MB    | ################################################################################################################# | 100% 
libsqlite-3.39.3     | 789 KB    | ################################################################################################################# | 100% 
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
#     $ conda activate MSMetaEnhancer
#
# To deactivate an active environment, use
#
#     $ conda deactivate

(base) [opc@metawards ~]$ conda activate MSMetaEnhancer
(MSMetaEnhancer) [opc@metawards ~]$ conda install --channel bioconda --channel conda-forge MSMetaEnhancer
Collecting package metadata (current_repodata.json): done
Solving environment: failed with initial frozen solve. Retrying with flexible solve.
Solving environment: failed with repodata from current_repodata.json, will retry with next repodata source.
Collecting package metadata (repodata.json): done
Solving environment: failed with initial frozen solve. Retrying with flexible solve.
Solving environment: - 
Found conflicts! Looking for incompatible packages.
This can take several minutes.  Press CTRL-C to abort.
failed                                                                                                                                                      

UnsatisfiableError: The following specifications were found to be incompatible with each other:

Output in format: Requested package -> Available versions

Package tk conflicts for:
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> tk[version='8.5.*|8.6.*|>=8.6.10,<8.7.0a0|>=8.6.11,<8.7.0a0|>=8.6.12,<8.7.0a0|>=8.6.9,<8.7.0a0|>=8.6.8,<8.7.0a0|>=8.6.7,<8.7.0a0']
python=3.9 -> tk[version='>=8.6.10,<8.7.0a0|>=8.6.11,<8.7.0a0|>=8.6.12,<8.7.0a0']
setuptools -> python[version='>=3.8'] -> tk[version='8.5.*|8.6.*|>=8.6.10,<8.7.0a0|>=8.6.11,<8.7.0a0|>=8.6.12,<8.7.0a0|>=8.6.9,<8.7.0a0|>=8.6.8,<8.7.0a0|>=8.6.7,<8.7.0a0']
pip -> python[version='>=3.7'] -> tk[version='8.5.*|8.6.*|>=8.6.10,<8.7.0a0|>=8.6.11,<8.7.0a0|>=8.6.12,<8.7.0a0|>=8.6.9,<8.7.0a0|>=8.6.8,<8.7.0a0|>=8.6.7,<8.7.0a0']
msmetaenhancer -> python[version='>=3.9'] -> tk[version='>=8.6.10,<8.7.0a0|>=8.6.11,<8.7.0a0|>=8.6.12,<8.7.0a0|>=8.6.9,<8.7.0a0|>=8.6.8,<8.7.0a0|>=8.6.7,<8.7.0a0']
tk

Package pip conflicts for:
setuptools -> python[version='>=3.8'] -> pip
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> pip
msmetaenhancer -> python[version='>=3.9'] -> pip
python=3.9 -> pip
pip

Package pypy3.7 conflicts for:
setuptools -> python[version='>=3.7,<3.8.0a0'] -> pypy3.7[version='7.3.*|7.3.3.*|7.3.4.*|7.3.5.*|7.3.7.*|>=7.3.4']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> pypy3.7[version='7.3.3.*|7.3.4.*|7.3.5.*|7.3.7.*|>=7.3.7|>=7.3.5|>=7.3.3']
setuptools -> pypy3.7[version='>=7.3.3|>=7.3.5|>=7.3.7']
msmetaenhancer -> aiohttp -> pypy3.7[version='7.3.3.*|7.3.4.*|7.3.5.*|7.3.7.*|>=7.3.3|>=7.3.4|>=7.3.7|>=7.3.5']
pip -> python[version='>=3.7'] -> pypy3.7[version='7.3.3.*|7.3.4.*|7.3.5.*|7.3.7.*|>=7.3.7|>=7.3.5|>=7.3.3']

Package _libgcc_mutex conflicts for:
libnsl -> libgcc-ng[version='>=9.4.0'] -> _libgcc_mutex==0.1=conda_forge
xz -> libgcc-ng[version='>=12'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
python=3.9 -> libgcc-ng[version='>=12'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
libffi -> libgcc-ng[version='>=9.4.0'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
tk -> libgcc-ng[version='>=9.4.0'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
libsqlite -> libgcc-ng[version='>=12'] -> _libgcc_mutex==0.1=conda_forge
sqlite -> libgcc-ng[version='>=12'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
libgomp -> _libgcc_mutex==0.1=conda_forge
libgcc-ng -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
_openmp_mutex -> _libgcc_mutex==0.1=conda_forge
ncurses -> libgcc-ng[version='>=10.3.0'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
libzlib -> libgcc-ng[version='>=12'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
readline -> libgcc-ng[version='>=12'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
bzip2 -> libgcc-ng[version='>=9.3.0'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']
_libgcc_mutex
libuuid -> libgcc-ng[version='>=9.3.0'] -> _libgcc_mutex[version='*|0.1',build='main|conda_forge']

Package zlib conflicts for:
python=3.9 -> zlib[version='>=1.2.11,<1.3.0a0']
setuptools -> python[version='>=3.8'] -> zlib[version='1.2.*|1.2.11|>=1.2.11,<1.3.0a0|>=1.2.12,<1.3.0a0|1.2.8|1.2.11.*']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> zlib[version='1.2.*|1.2.11|>=1.2.11,<1.3.0a0|1.2.8|1.2.11.*']
pip -> python[version='>=3.7'] -> zlib[version='1.2.*|1.2.11|>=1.2.11,<1.3.0a0|1.2.8|1.2.11.*']
sqlite -> zlib[version='>=1.2.11,<1.3.0a0|>=1.2.12,<1.3.0a0']
tk -> zlib[version='>=1.2.11,<1.3.0a0']
msmetaenhancer -> python[version='>=3.9'] -> zlib[version='>=1.2.11,<1.3.0a0']
python=3.9 -> sqlite[version='>=3.38.5,<4.0a0'] -> zlib[version='>=1.2.12,<1.3.0a0']

Package readline conflicts for:
setuptools -> python[version='>=3.8'] -> readline[version='6.2.*|7.0|>=7.0,<8.0a0|>=8.0,<9.0a0|>=8.1,<9.0a0|>=8.1.2,<9.0a0|7.0.*']
pip -> python[version='>=3.7'] -> readline[version='6.2.*|7.0|>=7.0,<8.0a0|>=8.0,<9.0a0|>=8.1,<9.0a0|>=8.1.2,<9.0a0|7.0.*']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> readline[version='6.2.*|7.0|>=7.0,<8.0a0|>=8.0,<9.0a0|>=8.1,<9.0a0|>=8.1.2,<9.0a0|7.0.*']
python=3.9 -> readline[version='>=8.0,<9.0a0|>=8.1,<9.0a0']
sqlite -> readline[version='6.2.*|7.0|7.0.*|>=7.0,<8.0a0|>=8.0,<9.0a0|>=8.1,<9.0a0|>=8.1.2,<9.0a0']
python=3.9 -> sqlite[version='>=3.38.5,<4.0a0'] -> readline[version='>=8.1.2,<9.0a0']
msmetaenhancer -> python[version='>=3.9'] -> readline[version='>=7.0,<8.0a0|>=8.0,<9.0a0|>=8.1,<9.0a0|>=8.1.2,<9.0a0']
readline

Package _openmp_mutex conflicts for:
xz -> libgcc-ng[version='>=12'] -> _openmp_mutex[version='>=4.5']
ncurses -> libgcc-ng[version='>=10.3.0'] -> _openmp_mutex[version='>=4.5']
libffi -> libgcc-ng[version='>=9.4.0'] -> _openmp_mutex[version='>=4.5']
tk -> libgcc-ng[version='>=9.4.0'] -> _openmp_mutex[version='>=4.5']
libsqlite -> libgcc-ng[version='>=12'] -> _openmp_mutex[version='>=4.5']
python=3.9 -> libgcc-ng[version='>=12'] -> _openmp_mutex[version='>=4.5']
libzlib -> libgcc-ng[version='>=12'] -> _openmp_mutex[version='>=4.5']
readline -> libgcc-ng[version='>=12'] -> _openmp_mutex[version='>=4.5']
sqlite -> libgcc-ng[version='>=12'] -> _openmp_mutex[version='>=4.5']
libnsl -> libgcc-ng[version='>=9.4.0'] -> _openmp_mutex[version='>=4.5']
libuuid -> libgcc-ng[version='>=9.3.0'] -> _openmp_mutex[version='>=4.5']
libgcc-ng -> _openmp_mutex[version='>=4.5']
_openmp_mutex
bzip2 -> libgcc-ng[version='>=9.3.0'] -> _openmp_mutex[version='>=4.5']

Package libffi conflicts for:
libffi
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> libffi[version='>=3.2.1,<3.3.0a0|>=3.3,<3.4.0a0|>=3.4.2,<3.5.0a0']
python=3.9 -> libffi[version='>=3.2.1,<3.3.0a0|>=3.3,<3.4.0a0|>=3.4.2,<3.5.0a0']
setuptools -> python[version='>=3.8'] -> libffi[version='>=3.2.1,<3.3.0a0|>=3.3,<3.4.0a0|>=3.4.2,<3.5.0a0']
msmetaenhancer -> python[version='>=3.9'] -> libffi[version='>=3.2.1,<3.3.0a0|>=3.3,<3.4.0a0|>=3.4.2,<3.5.0a0']
pip -> python[version='>=3.7'] -> libffi[version='>=3.2.1,<3.3.0a0|>=3.3,<3.4.0a0|>=3.4.2,<3.5.0a0']

Package libgcc-ng conflicts for:
sqlite -> libgcc-ng[version='>=10.3.0|>=12|>=9.4.0|>=9.3.0|>=7.5.0|>=7.3.0|>=4.9']
setuptools -> python[version='>=3.8'] -> libgcc-ng[version='>=10.3.0|>=12|>=9.4.0|>=9.3.0|>=7.5.0|>=7.3.0|>=4.9']
bzip2 -> libgcc-ng[version='>=4.9|>=7.3.0|>=7.5.0|>=9.3.0']
libffi -> libgcc-ng[version='>=4.9|>=7.3.0|>=7.5.0|>=9.4.0']
tk -> libzlib[version='>=1.2.11,<1.3.0a0'] -> libgcc-ng[version='>=10.3.0|>=12']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> libgcc-ng[version='>=10.3.0|>=12|>=9.4.0|>=9.3.0|>=7.5.0|>=7.3.0|>=4.9']
python=3.9 -> bzip2[version='>=1.0.8,<2.0a0'] -> libgcc-ng[version='>=4.9|>=7.3.0']
msmetaenhancer -> aiohttp -> libgcc-ng[version='>=10.3.0|>=9.4.0|>=9.3.0|>=7.5.0|>=7.3.0|>=4.9|>=7.2.0|>=12']
readline -> libgcc-ng[version='>=12|>=9.3.0|>=7.5.0|>=7.3.0|>=4.9']
python=3.9 -> libgcc-ng[version='>=10.3.0|>=12|>=9.4.0|>=9.3.0|>=7.5.0']
pip -> python[version='>=3.7'] -> libgcc-ng[version='>=10.3.0|>=12|>=9.4.0|>=9.3.0|>=7.5.0|>=7.3.0|>=4.9']
libnsl -> libgcc-ng[version='>=9.4.0']
readline -> ncurses[version='>=6.3,<7.0a0'] -> libgcc-ng[version='>=10.3.0|>=9.4.0']
tk -> libgcc-ng[version='>=4.9|>=7.3.0|>=7.5.0|>=9.4.0']
libgcc-ng
libsqlite -> libgcc-ng[version='>=12']
libuuid -> libgcc-ng[version='>=7.3.0|>=9.3.0']
xz -> libgcc-ng[version='>=12|>=7.5.0|>=7.3.0|>=4.9']
_openmp_mutex -> llvm-openmp[version='>=9.0.1'] -> libgcc-ng[version='>=7.3.0']
libzlib -> libgcc-ng[version='>=10.3.0|>=12|>=7.5.0']
ncurses -> libgcc-ng[version='>=10.3.0|>=9.4.0|>=7.5.0|>=7.3.0|>=4.9']

Package ncurses conflicts for:
pip -> python[version='>=3.7'] -> ncurses[version='5.9.*|5.9|>=6.1,<7.0.0a0|>=6.2,<6.3.0a0|>=6.3,<7.0a0|>=6.2,<7.0.0a0']
setuptools -> python[version='>=3.8'] -> ncurses[version='5.9.*|5.9|>=6.1,<7.0.0a0|>=6.2,<6.3.0a0|>=6.3,<7.0a0|>=6.2,<7.0.0a0']
python=3.9 -> ncurses[version='>=6.2,<7.0.0a0|>=6.3,<7.0a0']
msmetaenhancer -> python[version='>=3.9'] -> ncurses[version='>=6.1,<7.0.0a0|>=6.2,<6.3.0a0|>=6.3,<7.0a0|>=6.2,<7.0.0a0']
readline -> ncurses[version='5.9.*|>=6.1,<7.0.0a0|>=6.2,<7.0.0a0|>=6.3,<7.0a0']
python=3.9 -> readline[version='>=8.0,<9.0a0'] -> ncurses[version='>=6.1,<7.0.0a0']
sqlite -> ncurses[version='5.9|5.9.*|>=6.1,<7.0.0a0|>=6.2,<7.0.0a0|>=6.3,<7.0a0']
ncurses
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> ncurses[version='5.9.*|5.9|>=6.1,<7.0.0a0|>=6.2,<6.3.0a0|>=6.3,<7.0a0|>=6.2,<7.0.0a0']

Package packaging conflicts for:
wheel -> packaging[version='>=20.2']
pip -> wheel -> packaging[version='>=20.2']

Package libgomp conflicts for:
libgomp
libgcc-ng -> _openmp_mutex[version='>=4.5'] -> libgomp[version='>=7.3.0|>=7.5.0']
_openmp_mutex -> libgomp[version='>=7.3.0|>=7.5.0']

Package llvm-openmp conflicts for:
libgcc-ng -> _openmp_mutex[version='>=4.5'] -> llvm-openmp[version='>=9.0.1']
_openmp_mutex -> llvm-openmp[version='>=9.0.1']

Package libstdcxx-ng conflicts for:
setuptools -> python[version='>=3.8'] -> libstdcxx-ng[version='>=4.9|>=7.3.0|>=7.5.0|>=9.3.0|>=9.4.0']
python=3.9 -> libstdcxx-ng[version='>=7.5.0|>=9.3.0']
sqlite -> libstdcxx-ng[version='>=4.9|>=7.3.0']
sqlite -> ncurses[version='>=6.2,<7.0.0a0'] -> libstdcxx-ng[version='>=7.5.0']
ncurses -> libstdcxx-ng[version='>=4.9|>=7.3.0|>=7.5.0']
pip -> python[version='>=3.7'] -> libstdcxx-ng[version='>=4.9|>=7.3.0|>=7.5.0|>=9.3.0|>=9.4.0']
python=3.9 -> libffi[version='>=3.4.2,<3.5.0a0'] -> libstdcxx-ng[version='>=4.9|>=7.3.0|>=9.4.0']
libffi -> libstdcxx-ng[version='>=4.9|>=7.3.0|>=7.5.0|>=9.4.0']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> libstdcxx-ng[version='>=4.9|>=7.3.0|>=7.5.0|>=9.3.0|>=9.4.0']
msmetaenhancer -> pandas -> libstdcxx-ng[version='>=10.3.0|>=12|>=9.4.0|>=9.3.0|>=7.5.0|>=7.3.0|>=4.9']
_openmp_mutex -> llvm-openmp[version='>=9.0.1'] -> libstdcxx-ng[version='>=7.3.0']
readline -> ncurses[version='>=6.2,<7.0.0a0'] -> libstdcxx-ng[version='>=4.9|>=7.3.0|>=7.5.0']

Package sqlite conflicts for:
python=3.9 -> sqlite[version='>=3.33.0,<4.0a0|>=3.34.0,<4.0a0|>=3.35.5,<4.0a0|>=3.36.0,<4.0a0|>=3.37.0,<4.0a0|>=3.37.1,<4.0a0|>=3.38.5,<4.0a0']
python=3.9 -> pypy3.9=7.3.9 -> sqlite[version='>=3.38.2,<4.0a0|>=3.39.1,<4.0a0|>=3.39.2,<4.0a0']
msmetaenhancer -> python[version='>=3.9'] -> sqlite[version='>=3.24.0,<4.0a0|>=3.25.1,<4.0a0|>=3.25.2,<4.0a0|>=3.25.3,<4.0a0|>=3.26.0,<4.0a0|>=3.28.0,<4.0a0|>=3.30.1,<4.0a0|>=3.32.3,<4.0a0|>=3.33.0,<4.0a0|>=3.34.0,<4.0a0|>=3.35.5,<4.0a0|>=3.36.0,<4.0a0|>=3.37.0,<4.0a0|>=3.37.1,<4.0a0|>=3.38.5,<4.0a0']
pip -> python[version='>=3.7'] -> sqlite[version='3.13.*|3.20.*|>=3.24.0,<4.0a0|>=3.25.1,<4.0a0|>=3.25.2,<4.0a0|>=3.25.3,<4.0a0|>=3.26.0,<4.0a0|>=3.28.0,<4.0a0|>=3.30.1,<4.0a0|>=3.32.3,<4.0a0|>=3.33.0,<4.0a0|>=3.34.0,<4.0a0|>=3.35.5,<4.0a0|>=3.36.0,<4.0a0|>=3.37.0,<4.0a0|>=3.37.1,<4.0a0|>=3.38.5,<4.0a0|3.9.*']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> sqlite[version='3.13.*|3.20.*|>=3.24.0,<4.0a0|>=3.25.1,<4.0a0|>=3.25.2,<4.0a0|>=3.25.3,<4.0a0|>=3.26.0,<4.0a0|>=3.28.0,<4.0a0|>=3.30.1,<4.0a0|>=3.32.3,<4.0a0|>=3.33.0,<4.0a0|>=3.34.0,<4.0a0|>=3.35.5,<4.0a0|>=3.36.0,<4.0a0|>=3.37.0,<4.0a0|>=3.37.1,<4.0a0|>=3.38.5,<4.0a0|3.9.*']
setuptools -> python[version='>=3.8'] -> sqlite[version='3.13.*|3.20.*|>=3.24.0,<4.0a0|>=3.25.1,<4.0a0|>=3.25.2,<4.0a0|>=3.25.3,<4.0a0|>=3.26.0,<4.0a0|>=3.28.0,<4.0a0|>=3.30.1,<4.0a0|>=3.32.3,<4.0a0|>=3.33.0,<4.0a0|>=3.34.0,<4.0a0|>=3.35.5,<4.0a0|>=3.36.0,<4.0a0|>=3.37.0,<4.0a0|>=3.37.1,<4.0a0|>=3.38.5,<4.0a0|>=3.39.2,<4.0a0|>=3.39.1,<4.0a0|>=3.38.2,<4.0a0|>=3.35.4,<4.0a0|3.9.*']
sqlite

Package gdbm conflicts for:
python=3.9 -> pypy3.9=7.3.9 -> gdbm[version='>=1.18,<1.19.0a0']
setuptools -> pypy3.9[version='>=7.3.9'] -> gdbm[version='>=1.18,<1.19.0a0']

Package ld_impl_linux-64 conflicts for:
ld_impl_linux-64
pip -> python[version='>=3.7'] -> ld_impl_linux-64[version='>=2.34|>=2.36.1']
setuptools -> python[version='>=3.8'] -> ld_impl_linux-64[version='>=2.34|>=2.36.1']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> ld_impl_linux-64[version='>=2.34|>=2.36.1']
python=3.9 -> ld_impl_linux-64[version='>=2.36.1']
msmetaenhancer -> python[version='>=3.9'] -> ld_impl_linux-64[version='>=2.34|>=2.36.1']

Package libzlib conflicts for:
sqlite -> libzlib[version='>=1.2.11,<1.3.0a0|>=1.2.12,<1.3.0a0']
setuptools -> python[version='>=3.8'] -> libzlib[version='>=1.2.11,<1.3.0a0|>=1.2.12,<1.3.0a0']
_openmp_mutex -> llvm-openmp[version='>=9.0.1'] -> libzlib[version='>=1.2.11,<1.3.0a0']
pip -> python[version='>=3.7'] -> libzlib[version='>=1.2.11,<1.3.0a0|>=1.2.12,<1.3.0a0']
libsqlite -> libzlib[version='>=1.2.12,<1.3.0a0']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> libzlib[version='>=1.2.11,<1.3.0a0|>=1.2.12,<1.3.0a0']
python=3.9 -> libzlib[version='>=1.2.11,<1.3.0a0']
sqlite -> zlib[version='>=1.2.12,<1.3.0a0'] -> libzlib[version='1.2.11|1.2.11|1.2.11|1.2.12',build='h36c2ea0_1012|h166bdaf_1014|h166bdaf_0|h166bdaf_3|h166bdaf_2|h166bdaf_1|h36c2ea0_1013']
tk -> zlib[version='>=1.2.11,<1.3.0a0'] -> libzlib[version='1.2.11|1.2.11|1.2.11|1.2.12',build='h36c2ea0_1012|h166bdaf_1014|h166bdaf_0|h166bdaf_3|h166bdaf_2|h166bdaf_1|h36c2ea0_1013']
msmetaenhancer -> python[version='>=3.9'] -> libzlib[version='>=1.2.11,<1.3.0a0|>=1.2.12,<1.3.0a0']
tk -> libzlib[version='>=1.2.11,<1.3.0a0']
python=3.9 -> sqlite[version='>=3.38.5,<4.0a0'] -> libzlib[version='1.2.11|1.2.11|1.2.11|1.2.12|1.2.12|1.2.12|1.2.12|>=1.2.12,<1.3.0a0',build='h36c2ea0_1012|h166bdaf_1014|h166bdaf_0|h166bdaf_3|h166bdaf_2|h166bdaf_1|h36c2ea0_1013']
libzlib

Package libnsl conflicts for:
pip -> python[version='>=3.7'] -> libnsl[version='>=2.0.0,<2.1.0a0']
msmetaenhancer -> python[version='>=3.9'] -> libnsl[version='>=2.0.0,<2.1.0a0']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> libnsl[version='>=2.0.0,<2.1.0a0']
libnsl
setuptools -> python[version='>=3.8'] -> libnsl[version='>=2.0.0,<2.1.0a0']
python=3.9 -> libnsl[version='>=2.0.0,<2.1.0a0']

Package libuuid conflicts for:
setuptools -> python[version='>=3.8'] -> libuuid[version='>=2.32.1,<3.0a0']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> libuuid[version='>=2.32.1,<3.0a0']
pip -> python[version='>=3.7'] -> libuuid[version='>=2.32.1,<3.0a0']
python=3.9 -> libuuid[version='>=2.32.1,<3.0a0']
libuuid
msmetaenhancer -> python[version='>=3.9'] -> libuuid[version='>=2.32.1,<3.0a0']

Package openssl conflicts for:
python=3.9 -> pypy3.9=7.3.9 -> openssl[version='>=1.1.1q,<1.1.2a|>=3.0.5,<4.0a0']
pip -> python[version='>=3.7'] -> openssl[version='1.0.*|>=1.0.2o,<1.0.3a|>=1.0.2p,<1.0.3a|>=1.1.1a,<1.1.2a|>=1.1.1d,<1.1.2a|>=1.1.1e,<1.1.2a|>=1.1.1f,<1.1.2a|>=1.1.1g,<1.1.2a|>=1.1.1h,<1.1.2a|>=1.1.1i,<1.1.2a|>=1.1.1j,<1.1.2a|>=1.1.1k,<1.1.2a|>=1.1.1l,<1.1.2a|>=1.1.1n,<1.1.2a|>=1.1.1o,<1.1.2a|>=1.1.1q,<1.1.2a|>=3.0.5,<4.0a0|>=3.0.3,<4.0a0|>=3.0.2,<4.0a0|>=3.0.0,<4.0a0']
setuptools -> python[version='>=3.8'] -> openssl[version='1.0.*|>=1.0.2o,<1.0.3a|>=1.0.2p,<1.0.3a|>=1.1.1a,<1.1.2a|>=1.1.1d,<1.1.2a|>=1.1.1e,<1.1.2a|>=1.1.1f,<1.1.2a|>=1.1.1g,<1.1.2a|>=1.1.1h,<1.1.2a|>=1.1.1i,<1.1.2a|>=1.1.1j,<1.1.2a|>=1.1.1k,<1.1.2a|>=1.1.1l,<1.1.2a|>=1.1.1n,<1.1.2a|>=1.1.1o,<1.1.2a|>=1.1.1q,<1.1.2a|>=3.0.5,<4.0a0|>=3.0.3,<4.0a0|>=3.0.2,<4.0a0|>=3.0.0,<4.0a0']
msmetaenhancer -> python[version='>=3.9'] -> openssl[version='>=1.0.2o,<1.0.3a|>=1.0.2p,<1.0.3a|>=1.1.1a,<1.1.2a|>=1.1.1d,<1.1.2a|>=1.1.1e,<1.1.2a|>=1.1.1f,<1.1.2a|>=1.1.1g,<1.1.2a|>=1.1.1h,<1.1.2a|>=1.1.1i,<1.1.2a|>=1.1.1j,<1.1.2a|>=1.1.1k,<1.1.2a|>=1.1.1l,<1.1.2a|>=1.1.1n,<1.1.2a|>=1.1.1o,<1.1.2a|>=1.1.1q,<1.1.2a|>=3.0.5,<4.0a0|>=3.0.3,<4.0a0|>=3.0.2,<4.0a0|>=3.0.0,<4.0a0']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> openssl[version='1.0.*|>=1.0.2o,<1.0.3a|>=1.0.2p,<1.0.3a|>=1.1.1a,<1.1.2a|>=1.1.1d,<1.1.2a|>=1.1.1e,<1.1.2a|>=1.1.1f,<1.1.2a|>=1.1.1g,<1.1.2a|>=1.1.1h,<1.1.2a|>=1.1.1i,<1.1.2a|>=1.1.1j,<1.1.2a|>=1.1.1k,<1.1.2a|>=1.1.1l,<1.1.2a|>=1.1.1n,<1.1.2a|>=1.1.1o,<1.1.2a|>=1.1.1q,<1.1.2a|>=3.0.5,<4.0a0|>=3.0.3,<4.0a0|>=3.0.2,<4.0a0|>=3.0.0,<4.0a0']
openssl
python=3.9 -> openssl[version='>=1.1.1h,<1.1.2a|>=1.1.1i,<1.1.2a|>=1.1.1j,<1.1.2a|>=1.1.1k,<1.1.2a|>=1.1.1l,<1.1.2a|>=1.1.1n,<1.1.2a|>=1.1.1o,<1.1.2a|>=3.0.3,<4.0a0|>=3.0.2,<4.0a0|>=3.0.0,<4.0a0']

Package xz conflicts for:
python=3.9 -> xz[version='>=5.2.5,<5.3.0a0']
msmetaenhancer -> python[version='>=3.9'] -> xz[version='>=5.2.3,<5.3.0a0|>=5.2.4,<5.3.0a0|>=5.2.5,<5.3.0a0|>=5.2.6,<5.3.0a0']
python=3.9 -> pypy3.9=7.3.9 -> xz[version='>=5.2.6,<5.3.0a0']
xz
setuptools -> python[version='>=3.8'] -> xz[version='5.0.*|5.2.*|>=5.2.3,<5.3.0a0|>=5.2.4,<5.3.0a0|>=5.2.5,<5.3.0a0|>=5.2.6,<5.3.0a0']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> xz[version='5.0.*|5.2.*|>=5.2.3,<5.3.0a0|>=5.2.4,<5.3.0a0|>=5.2.5,<5.3.0a0|>=5.2.6,<5.3.0a0']
pip -> python[version='>=3.7'] -> xz[version='5.0.*|5.2.*|>=5.2.3,<5.3.0a0|>=5.2.4,<5.3.0a0|>=5.2.5,<5.3.0a0|>=5.2.6,<5.3.0a0']

Package tzdata conflicts for:
tzdata
setuptools -> python[version='>=3.8'] -> tzdata
python=3.9 -> tzdata
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> tzdata
msmetaenhancer -> python[version='>=3.9'] -> tzdata
pip -> python[version='>=3.7'] -> tzdata

Package libsqlite conflicts for:
setuptools -> python[version='>=3.8'] -> libsqlite[version='>=3.39.2,<4.0a0']
sqlite -> libsqlite[version='3.39.2|3.39.3',build='h753d276_0|h753d276_1']
python=3.9 -> sqlite[version='>=3.38.5,<4.0a0'] -> libsqlite[version='3.39.2|3.39.3|>=3.39.2,<4.0a0',build='h753d276_0|h753d276_1']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> libsqlite[version='>=3.39.2,<4.0a0']
pip -> python[version='>=3.7'] -> libsqlite[version='>=3.39.2,<4.0a0']
msmetaenhancer -> python[version='>=3.9'] -> libsqlite[version='>=3.39.2,<4.0a0']
libsqlite

Package bzip2 conflicts for:
msmetaenhancer -> python[version='>=3.9'] -> bzip2[version='>=1.0.6,<2.0a0|>=1.0.8,<2.0a0']
bzip2
python=3.9 -> bzip2[version='>=1.0.8,<2.0a0']
pip -> python[version='>=3.7'] -> bzip2[version='>=1.0.6,<2.0a0|>=1.0.8,<2.0a0']
setuptools -> python[version='>=3.8'] -> bzip2[version='>=1.0.6,<2.0a0|>=1.0.8,<2.0a0']
wheel -> python[version='!=3.0,!=3.1,!=3.2,!=3.3,!=3.4'] -> bzip2[version='>=1.0.6,<2.0a0|>=1.0.8,<2.0a0']

Package six conflicts for:
msmetaenhancer -> rdkit -> six
wheel -> packaging[version='>=20.2'] -> six

Package wheel conflicts for:
pip -> wheel
python=3.9 -> pip -> wheel
wheel

Package ca-certificates conflicts for:
python=3.9 -> openssl[version='>=3.0.3,<4.0a0'] -> ca-certificates
ca-certificates
Note that strict channel priority may have removed packages required for satisfiability.

I suspect the versions of too many packages are being pinned.

Could you see if you can install into a new miniconda? If you can, can you let me know how you did it and what the versions of packages your conda tries to install?

Thanks :-)

hechth commented 2 years ago

@chryswoods I'll check - likely it is pinning the python version to 3.9 which is the issue. Which linux distro is this on?

chryswoods commented 2 years ago

Ok - I've fixed it. The conda channel order priority was borked on my computer. I removed ~/.conda and ~/.condarc, removed ~/miniconda3 and then unpacked everything and tried again. It is now working :-)

I've run all of the tests and get these test failures;

(MSMetaEnhancer) [opc@metawards MSMetaEnhancer]$ pytest tests/
=================================================================== test session starts ====================================================================
platform linux -- Python 3.9.13, pytest-7.1.3, pluggy-1.0.0
rootdir: /home/opc/MSMetaEnhancer
plugins: cov-3.0.0, dependency-0.5.1, aiohttp-0.3.0
collected 41 items                                                                                                                                         

tests/test_BridgeDB.py ...                                                                                                                           [  7%]
tests/test_CIR.py ...                                                                                                                                [ 14%]
tests/test_CTS.py ....                                                                                                                               [ 24%]
tests/test_IDSM.py X..                                                                                                                               [ 31%]
tests/test_NLM.py ...                                                                                                                                [ 39%]
tests/test_PubChem.py .....                                                                                                                          [ 51%]
tests/test_annotator.py ....                                                                                                                         [ 60%]
tests/test_application.py ..                                                                                                                         [ 65%]
tests/test_converter.py .FFFFFF....                                                                                                                  [ 92%]
tests/test_curator.py ...                                                                                                                            [100%]

========================================================================= FAILURES =========================================================================
___________________________________________________ test_loop_request_circuit_breaker_get[TimeoutError] ____________________________________________________

self = <aiocircuitbreaker.aiocircuitbreaker.CircuitBreaker object at 0x7fa01e80ff10>, func = <function WebConverter.make_request at 0x7fa01e7d2040>
args = (<MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ceb0f40>, '/', 'GET', None, None), kwargs = {}

    async def call(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
        """
        Calls the decorated function and applies the circuit breaker
        rules on success or failure
        :param func: Decorated async function
        """
        with self:
>           return await func(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ceb0f40>, url = '/', method = 'GET', data = None, headers = {}

    @circuit(failure_threshold=FAILURE_THRESHOLD,
             expected_exception=Union[TimeoutError, ServerDisconnectedError, ClientConnectorError],
             fallback_function=ServiceNotAvailable.raise_circuitbreaker)
    async def make_request(self, url, method, data, headers):
        """
        Enter a circuit breaker loop and execute request with type depending on specified method.

        :param url: converter URL
        :param method: GET/POST
        :param data: given arguments for POST request
        :param headers: optional headers for the request
        :return: obtained response
        """
        if headers is None:
            headers = dict()
        if method == 'GET':
>           async with self.session.get(url, headers=headers) as response:

MSMetaEnhancer/libs/converters/web/WebConverter.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656661344'>, args = ('/',), kwargs = {'headers': {}}

    def __call__(_mock_self, *args, **kwargs):
        # can't use self in-case a function / method we are mocking uses self
        # in the signature
        _mock_self._mock_check_sig(*args, **kwargs)
        _mock_self._increment_mock_call(*args, **kwargs)
>       return _mock_self._mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656661344'>, args = ('/',), kwargs = {'headers': {}}

    def _mock_call(_mock_self, *args, **kwargs):
>       return _mock_self._execute_mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1104: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656661344'>, args = ('/',), kwargs = {'headers': {}}, self = <Mock name='mock.get' id='140325656661344'>
effect = <class 'asyncio.exceptions.TimeoutError'>

    def _execute_mock_call(_mock_self, *args, **kwargs):
        self = _mock_self
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
>               raise effect
E               asyncio.exceptions.TimeoutError

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1161: TimeoutError

During handling of the above exception, another exception occurred:

failing_session_mock = <AsyncMock id='140325657133696'>

    async def test_loop_request_circuit_breaker_get(failing_session_mock):
        converter = WebConverter(failing_session_mock)

        with pytest.raises(ServiceNotAvailable):
>           await converter.loop_request('/', 'GET', None, None)

tests/test_converter.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
MSMetaEnhancer/libs/converters/web/WebConverter.py:105: in loop_request
    return await self.make_request(url, method, data, headers)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:77: in wrapper
    return await self.call(function, *args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: in call
    return await func(*args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:55: in __exit__
    if exc_type and issubclass(exc_type, self._expected_exception):  # type: ignore
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = typing.Union[asyncio.exceptions.TimeoutError, aiohttp.client_exceptions.ServerDisconnectedError, aiohttp.client_exceptions.ClientConnectorError]
cls = <class 'asyncio.exceptions.TimeoutError'>

    def __subclasscheck__(self, cls):
>       raise TypeError("Subscripted generics cannot be used with"
                        " class and instance checks")
E       TypeError: Subscripted generics cannot be used with class and instance checks

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/typing.py:723: TypeError
______________________________________________ test_loop_request_circuit_breaker_get[ServerDisconnectedError] ______________________________________________

self = <aiocircuitbreaker.aiocircuitbreaker.CircuitBreaker object at 0x7fa01e80ff10>, func = <function WebConverter.make_request at 0x7fa01e7d2040>
args = (<MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce2a730>, '/', 'GET', None, None), kwargs = {}

    async def call(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
        """
        Calls the decorated function and applies the circuit breaker
        rules on success or failure
        :param func: Decorated async function
        """
        with self:
>           return await func(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce2a730>, url = '/', method = 'GET', data = None, headers = {}

    @circuit(failure_threshold=FAILURE_THRESHOLD,
             expected_exception=Union[TimeoutError, ServerDisconnectedError, ClientConnectorError],
             fallback_function=ServiceNotAvailable.raise_circuitbreaker)
    async def make_request(self, url, method, data, headers):
        """
        Enter a circuit breaker loop and execute request with type depending on specified method.

        :param url: converter URL
        :param method: GET/POST
        :param data: given arguments for POST request
        :param headers: optional headers for the request
        :return: obtained response
        """
        if headers is None:
            headers = dict()
        if method == 'GET':
>           async with self.session.get(url, headers=headers) as response:

MSMetaEnhancer/libs/converters/web/WebConverter.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656110272'>, args = ('/',), kwargs = {'headers': {}}

    def __call__(_mock_self, *args, **kwargs):
        # can't use self in-case a function / method we are mocking uses self
        # in the signature
        _mock_self._mock_check_sig(*args, **kwargs)
        _mock_self._increment_mock_call(*args, **kwargs)
>       return _mock_self._mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656110272'>, args = ('/',), kwargs = {'headers': {}}

    def _mock_call(_mock_self, *args, **kwargs):
>       return _mock_self._execute_mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1104: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656110272'>, args = ('/',), kwargs = {'headers': {}}, self = <Mock name='mock.get' id='140325656110272'>
effect = <class 'aiohttp.client_exceptions.ServerDisconnectedError'>

    def _execute_mock_call(_mock_self, *args, **kwargs):
        self = _mock_self
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
>               raise effect
E               aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1161: ServerDisconnectedError

During handling of the above exception, another exception occurred:

failing_session_mock = <AsyncMock id='140325655714448'>

    async def test_loop_request_circuit_breaker_get(failing_session_mock):
        converter = WebConverter(failing_session_mock)

        with pytest.raises(ServiceNotAvailable):
>           await converter.loop_request('/', 'GET', None, None)

tests/test_converter.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
MSMetaEnhancer/libs/converters/web/WebConverter.py:105: in loop_request
    return await self.make_request(url, method, data, headers)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:77: in wrapper
    return await self.call(function, *args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: in call
    return await func(*args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:55: in __exit__
    if exc_type and issubclass(exc_type, self._expected_exception):  # type: ignore
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = typing.Union[asyncio.exceptions.TimeoutError, aiohttp.client_exceptions.ServerDisconnectedError, aiohttp.client_exceptions.ClientConnectorError]
cls = <class 'aiohttp.client_exceptions.ServerDisconnectedError'>

    def __subclasscheck__(self, cls):
>       raise TypeError("Subscripted generics cannot be used with"
                        " class and instance checks")
E       TypeError: Subscripted generics cannot be used with class and instance checks

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/typing.py:723: TypeError
_______________________________________________ test_loop_request_circuit_breaker_get[failing_session_mock2] _______________________________________________

self = <aiocircuitbreaker.aiocircuitbreaker.CircuitBreaker object at 0x7fa01e80ff10>, func = <function WebConverter.make_request at 0x7fa01e7d2040>
args = (<MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce4ae20>, '/', 'GET', None, None), kwargs = {}

    async def call(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
        """
        Calls the decorated function and applies the circuit breaker
        rules on success or failure
        :param func: Decorated async function
        """
        with self:
>           return await func(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce4ae20>, url = '/', method = 'GET', data = None, headers = {}

    @circuit(failure_threshold=FAILURE_THRESHOLD,
             expected_exception=Union[TimeoutError, ServerDisconnectedError, ClientConnectorError],
             fallback_function=ServiceNotAvailable.raise_circuitbreaker)
    async def make_request(self, url, method, data, headers):
        """
        Enter a circuit breaker loop and execute request with type depending on specified method.

        :param url: converter URL
        :param method: GET/POST
        :param data: given arguments for POST request
        :param headers: optional headers for the request
        :return: obtained response
        """
        if headers is None:
            headers = dict()
        if method == 'GET':
>           async with self.session.get(url, headers=headers) as response:

MSMetaEnhancer/libs/converters/web/WebConverter.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656242256'>, args = ('/',), kwargs = {'headers': {}}

    def __call__(_mock_self, *args, **kwargs):
        # can't use self in-case a function / method we are mocking uses self
        # in the signature
        _mock_self._mock_check_sig(*args, **kwargs)
        _mock_self._increment_mock_call(*args, **kwargs)
>       return _mock_self._mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656242256'>, args = ('/',), kwargs = {'headers': {}}

    def _mock_call(_mock_self, *args, **kwargs):
>       return _mock_self._execute_mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1104: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656242256'>, args = ('/',), kwargs = {'headers': {}}, self = <Mock name='mock.get' id='140325656242256'>
effect = ClientConnectorError(None, OSError())

    def _execute_mock_call(_mock_self, *args, **kwargs):
        self = _mock_self
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
>               raise effect
E               aiohttp.client_exceptions.ClientConnectorError: <unprintable ClientConnectorError object>

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1161: ClientConnectorError

During handling of the above exception, another exception occurred:

failing_session_mock = <AsyncMock id='140325657300320'>

    async def test_loop_request_circuit_breaker_get(failing_session_mock):
        converter = WebConverter(failing_session_mock)

        with pytest.raises(ServiceNotAvailable):
>           await converter.loop_request('/', 'GET', None, None)

tests/test_converter.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
MSMetaEnhancer/libs/converters/web/WebConverter.py:105: in loop_request
    return await self.make_request(url, method, data, headers)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:77: in wrapper
    return await self.call(function, *args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: in call
    return await func(*args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:55: in __exit__
    if exc_type and issubclass(exc_type, self._expected_exception):  # type: ignore
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = typing.Union[asyncio.exceptions.TimeoutError, aiohttp.client_exceptions.ServerDisconnectedError, aiohttp.client_exceptions.ClientConnectorError]
cls = <class 'aiohttp.client_exceptions.ClientConnectorError'>

    def __subclasscheck__(self, cls):
>       raise TypeError("Subscripted generics cannot be used with"
                        " class and instance checks")
E       TypeError: Subscripted generics cannot be used with class and instance checks

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/typing.py:723: TypeError
___________________________________________________ test_loop_request_circuit_breaker_post[TimeoutError] ___________________________________________________

self = <aiocircuitbreaker.aiocircuitbreaker.CircuitBreaker object at 0x7fa01e80ff10>, func = <function WebConverter.make_request at 0x7fa01e7d2040>
args = (<MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce9a8b0>, '/', 'POST', {'inchi': 'inchi'}, None), kwargs = {}

    async def call(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
        """
        Calls the decorated function and applies the circuit breaker
        rules on success or failure
        :param func: Decorated async function
        """
        with self:
>           return await func(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce9a8b0>, url = '/', method = 'POST'
data = <MultiDict('inchi': 'inchi')>, headers = {}

    @circuit(failure_threshold=FAILURE_THRESHOLD,
             expected_exception=Union[TimeoutError, ServerDisconnectedError, ClientConnectorError],
             fallback_function=ServiceNotAvailable.raise_circuitbreaker)
    async def make_request(self, url, method, data, headers):
        """
        Enter a circuit breaker loop and execute request with type depending on specified method.

        :param url: converter URL
        :param method: GET/POST
        :param data: given arguments for POST request
        :param headers: optional headers for the request
        :return: obtained response
        """
        if headers is None:
            headers = dict()
        if method == 'GET':
            async with self.session.get(url, headers=headers) as response:
                return await self.process_request(response, url, method)
        else:
            data = MultiDict(data)
>           async with self.session.post(url, data=data, headers=headers) as response:

MSMetaEnhancer/libs/converters/web/WebConverter.py:90: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.post' id='140325656570080'>, args = ('/',), kwargs = {'data': <MultiDict('inchi': 'inchi')>, 'headers': {}}

    def __call__(_mock_self, *args, **kwargs):
        # can't use self in-case a function / method we are mocking uses self
        # in the signature
        _mock_self._mock_check_sig(*args, **kwargs)
        _mock_self._increment_mock_call(*args, **kwargs)
>       return _mock_self._mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.post' id='140325656570080'>, args = ('/',), kwargs = {'data': <MultiDict('inchi': 'inchi')>, 'headers': {}}

    def _mock_call(_mock_self, *args, **kwargs):
>       return _mock_self._execute_mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1104: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.post' id='140325656570080'>, args = ('/',), kwargs = {'data': <MultiDict('inchi': 'inchi')>, 'headers': {}}
self = <Mock name='mock.post' id='140325656570080'>, effect = <class 'asyncio.exceptions.TimeoutError'>

    def _execute_mock_call(_mock_self, *args, **kwargs):
        self = _mock_self
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
>               raise effect
E               asyncio.exceptions.TimeoutError

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1161: TimeoutError

During handling of the above exception, another exception occurred:

failing_session_mock = <AsyncMock id='140325657293968'>

    async def test_loop_request_circuit_breaker_post(failing_session_mock):
        converter = WebConverter(failing_session_mock)
        data = {'inchi': 'inchi'}

        with pytest.raises(ServiceNotAvailable):
>           await converter.loop_request('/', 'POST', data, None)

tests/test_converter.py:94: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
MSMetaEnhancer/libs/converters/web/WebConverter.py:105: in loop_request
    return await self.make_request(url, method, data, headers)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:77: in wrapper
    return await self.call(function, *args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: in call
    return await func(*args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:55: in __exit__
    if exc_type and issubclass(exc_type, self._expected_exception):  # type: ignore
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = typing.Union[asyncio.exceptions.TimeoutError, aiohttp.client_exceptions.ServerDisconnectedError, aiohttp.client_exceptions.ClientConnectorError]
cls = <class 'asyncio.exceptions.TimeoutError'>

    def __subclasscheck__(self, cls):
>       raise TypeError("Subscripted generics cannot be used with"
                        " class and instance checks")
E       TypeError: Subscripted generics cannot be used with class and instance checks

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/typing.py:723: TypeError
_____________________________________________ test_loop_request_circuit_breaker_post[ServerDisconnectedError] ______________________________________________

self = <aiocircuitbreaker.aiocircuitbreaker.CircuitBreaker object at 0x7fa01e80ff10>, func = <function WebConverter.make_request at 0x7fa01e7d2040>
args = (<MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce1bb80>, '/', 'POST', {'inchi': 'inchi'}, None), kwargs = {}

    async def call(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
        """
        Calls the decorated function and applies the circuit breaker
        rules on success or failure
        :param func: Decorated async function
        """
        with self:
>           return await func(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce1bb80>, url = '/', method = 'POST'
data = <MultiDict('inchi': 'inchi')>, headers = {}

    @circuit(failure_threshold=FAILURE_THRESHOLD,
             expected_exception=Union[TimeoutError, ServerDisconnectedError, ClientConnectorError],
             fallback_function=ServiceNotAvailable.raise_circuitbreaker)
    async def make_request(self, url, method, data, headers):
        """
        Enter a circuit breaker loop and execute request with type depending on specified method.

        :param url: converter URL
        :param method: GET/POST
        :param data: given arguments for POST request
        :param headers: optional headers for the request
        :return: obtained response
        """
        if headers is None:
            headers = dict()
        if method == 'GET':
            async with self.session.get(url, headers=headers) as response:
                return await self.process_request(response, url, method)
        else:
            data = MultiDict(data)
>           async with self.session.post(url, data=data, headers=headers) as response:

MSMetaEnhancer/libs/converters/web/WebConverter.py:90: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.post' id='140325656051424'>, args = ('/',), kwargs = {'data': <MultiDict('inchi': 'inchi')>, 'headers': {}}

    def __call__(_mock_self, *args, **kwargs):
        # can't use self in-case a function / method we are mocking uses self
        # in the signature
        _mock_self._mock_check_sig(*args, **kwargs)
        _mock_self._increment_mock_call(*args, **kwargs)
>       return _mock_self._mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.post' id='140325656051424'>, args = ('/',), kwargs = {'data': <MultiDict('inchi': 'inchi')>, 'headers': {}}

    def _mock_call(_mock_self, *args, **kwargs):
>       return _mock_self._execute_mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1104: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.post' id='140325656051424'>, args = ('/',), kwargs = {'data': <MultiDict('inchi': 'inchi')>, 'headers': {}}
self = <Mock name='mock.post' id='140325656051424'>, effect = <class 'aiohttp.client_exceptions.ServerDisconnectedError'>

    def _execute_mock_call(_mock_self, *args, **kwargs):
        self = _mock_self
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
>               raise effect
E               aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1161: ServerDisconnectedError

During handling of the above exception, another exception occurred:

failing_session_mock = <AsyncMock id='140325655801136'>

    async def test_loop_request_circuit_breaker_post(failing_session_mock):
        converter = WebConverter(failing_session_mock)
        data = {'inchi': 'inchi'}

        with pytest.raises(ServiceNotAvailable):
>           await converter.loop_request('/', 'POST', data, None)

tests/test_converter.py:94: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
MSMetaEnhancer/libs/converters/web/WebConverter.py:105: in loop_request
    return await self.make_request(url, method, data, headers)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:77: in wrapper
    return await self.call(function, *args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: in call
    return await func(*args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:55: in __exit__
    if exc_type and issubclass(exc_type, self._expected_exception):  # type: ignore
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = typing.Union[asyncio.exceptions.TimeoutError, aiohttp.client_exceptions.ServerDisconnectedError, aiohttp.client_exceptions.ClientConnectorError]
cls = <class 'aiohttp.client_exceptions.ServerDisconnectedError'>

    def __subclasscheck__(self, cls):
>       raise TypeError("Subscripted generics cannot be used with"
                        " class and instance checks")
E       TypeError: Subscripted generics cannot be used with class and instance checks

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/typing.py:723: TypeError
______________________________________________ test_loop_request_circuit_breaker_post[failing_session_mock2] _______________________________________________

self = <aiocircuitbreaker.aiocircuitbreaker.CircuitBreaker object at 0x7fa01e80ff10>, func = <function WebConverter.make_request at 0x7fa01e7d2040>
args = (<MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ceb1280>, '/', 'POST', {'inchi': 'inchi'}, None), kwargs = {}

    async def call(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
        """
        Calls the decorated function and applies the circuit breaker
        rules on success or failure
        :param func: Decorated async function
        """
        with self:
>           return await func(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ceb1280>, url = '/', method = 'POST'
data = <MultiDict('inchi': 'inchi')>, headers = {}

    @circuit(failure_threshold=FAILURE_THRESHOLD,
             expected_exception=Union[TimeoutError, ServerDisconnectedError, ClientConnectorError],
             fallback_function=ServiceNotAvailable.raise_circuitbreaker)
    async def make_request(self, url, method, data, headers):
        """
        Enter a circuit breaker loop and execute request with type depending on specified method.

        :param url: converter URL
        :param method: GET/POST
        :param data: given arguments for POST request
        :param headers: optional headers for the request
        :return: obtained response
        """
        if headers is None:
            headers = dict()
        if method == 'GET':
            async with self.session.get(url, headers=headers) as response:
                return await self.process_request(response, url, method)
        else:
            data = MultiDict(data)
>           async with self.session.post(url, data=data, headers=headers) as response:

MSMetaEnhancer/libs/converters/web/WebConverter.py:90: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.post' id='140325656663136'>, args = ('/',), kwargs = {'data': <MultiDict('inchi': 'inchi')>, 'headers': {}}

    def __call__(_mock_self, *args, **kwargs):
        # can't use self in-case a function / method we are mocking uses self
        # in the signature
        _mock_self._mock_check_sig(*args, **kwargs)
        _mock_self._increment_mock_call(*args, **kwargs)
>       return _mock_self._mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.post' id='140325656663136'>, args = ('/',), kwargs = {'data': <MultiDict('inchi': 'inchi')>, 'headers': {}}

    def _mock_call(_mock_self, *args, **kwargs):
>       return _mock_self._execute_mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1104: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.post' id='140325656663136'>, args = ('/',), kwargs = {'data': <MultiDict('inchi': 'inchi')>, 'headers': {}}
self = <Mock name='mock.post' id='140325656663136'>, effect = ClientConnectorError(None, OSError())

    def _execute_mock_call(_mock_self, *args, **kwargs):
        self = _mock_self
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
>               raise effect

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1161: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <aiocircuitbreaker.aiocircuitbreaker.CircuitBreaker object at 0x7fa01e80ff10>, func = <function WebConverter.make_request at 0x7fa01e7d2040>
args = (<MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce4ae20>, '/', 'GET', None, None), kwargs = {}

    async def call(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
        """
        Calls the decorated function and applies the circuit breaker
        rules on success or failure
        :param func: Decorated async function
        """
        with self:
>           return await func(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MSMetaEnhancer.libs.converters.web.WebConverter.WebConverter object at 0x7fa01ce4ae20>, url = '/', method = 'GET', data = None, headers = {}

    @circuit(failure_threshold=FAILURE_THRESHOLD,
             expected_exception=Union[TimeoutError, ServerDisconnectedError, ClientConnectorError],
             fallback_function=ServiceNotAvailable.raise_circuitbreaker)
    async def make_request(self, url, method, data, headers):
        """
        Enter a circuit breaker loop and execute request with type depending on specified method.

        :param url: converter URL
        :param method: GET/POST
        :param data: given arguments for POST request
        :param headers: optional headers for the request
        :return: obtained response
        """
        if headers is None:
            headers = dict()
        if method == 'GET':
>           async with self.session.get(url, headers=headers) as response:

MSMetaEnhancer/libs/converters/web/WebConverter.py:86: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656242256'>, args = ('/',), kwargs = {'headers': {}}

    def __call__(_mock_self, *args, **kwargs):
        # can't use self in-case a function / method we are mocking uses self
        # in the signature
        _mock_self._mock_check_sig(*args, **kwargs)
        _mock_self._increment_mock_call(*args, **kwargs)
>       return _mock_self._mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656242256'>, args = ('/',), kwargs = {'headers': {}}

    def _mock_call(_mock_self, *args, **kwargs):
>       return _mock_self._execute_mock_call(*args, **kwargs)

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1104: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

_mock_self = <Mock name='mock.get' id='140325656242256'>, args = ('/',), kwargs = {'headers': {}}, self = <Mock name='mock.get' id='140325656242256'>
effect = ClientConnectorError(None, OSError())

    def _execute_mock_call(_mock_self, *args, **kwargs):
        self = _mock_self
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method

        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
>               raise effect
E               aiohttp.client_exceptions.ClientConnectorError: <unprintable ClientConnectorError object>

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/mock/mock.py:1161: ClientConnectorError

During handling of the above exception, another exception occurred:

failing_session_mock = <AsyncMock id='140325655730976'>

    async def test_loop_request_circuit_breaker_post(failing_session_mock):
        converter = WebConverter(failing_session_mock)
        data = {'inchi': 'inchi'}

        with pytest.raises(ServiceNotAvailable):
>           await converter.loop_request('/', 'POST', data, None)

tests/test_converter.py:94: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
MSMetaEnhancer/libs/converters/web/WebConverter.py:105: in loop_request
    return await self.make_request(url, method, data, headers)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:77: in wrapper
    return await self.call(function, *args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:91: in call
    return await func(*args, **kwargs)
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/aiocircuitbreaker/aiocircuitbreaker.py:55: in __exit__
    if exc_type and issubclass(exc_type, self._expected_exception):  # type: ignore
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = typing.Union[asyncio.exceptions.TimeoutError, aiohttp.client_exceptions.ServerDisconnectedError, aiohttp.client_exceptions.ClientConnectorError]
cls = <class 'aiohttp.client_exceptions.ClientConnectorError'>

    def __subclasscheck__(self, cls):
>       raise TypeError("Subscripted generics cannot be used with"
                        " class and instance checks")
E       TypeError: Subscripted generics cannot be used with class and instance checks

../miniconda3/envs/MSMetaEnhancer/lib/python3.9/typing.py:723: TypeError
===================================================================== warnings summary =====================================================================
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/pyteomics/auxiliary/patch.py:12
../miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/pyteomics/auxiliary/patch.py:12
  /home/opc/miniconda3/envs/MSMetaEnhancer/lib/python3.9/site-packages/pyteomics/auxiliary/patch.py:12: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.
    if LooseVersion(pv) < LooseVersion('0.17'):

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================================================= short test summary info ==================================================================
FAILED tests/test_converter.py::test_loop_request_circuit_breaker_get[TimeoutError] - TypeError: Subscripted generics cannot be used with class and insta...
FAILED tests/test_converter.py::test_loop_request_circuit_breaker_get[ServerDisconnectedError] - TypeError: Subscripted generics cannot be used with clas...
FAILED tests/test_converter.py::test_loop_request_circuit_breaker_get[failing_session_mock2] - TypeError: Subscripted generics cannot be used with class ...
FAILED tests/test_converter.py::test_loop_request_circuit_breaker_post[TimeoutError] - TypeError: Subscripted generics cannot be used with class and inst...
FAILED tests/test_converter.py::test_loop_request_circuit_breaker_post[ServerDisconnectedError] - TypeError: Subscripted generics cannot be used with cla...
FAILED tests/test_converter.py::test_loop_request_circuit_breaker_post[failing_session_mock2] - TypeError: Subscripted generics cannot be used with class...
=================================================== 6 failed, 34 passed, 1 xpassed, 2 warnings in 37.07s ===================================================
chryswoods commented 2 years ago

(the OS is Oracle Linux 7.9, which is heavily based on RedHat Enterprise 7.9)

chryswoods commented 2 years ago

I am away on extended leave and won't be able to look at this again until November. I am happy for the paper to be published once all of the unit tests pass.

hechth commented 2 years ago

@chryswoods We just merged a PR which contains fixes to the unit tests. Maybe @marshallmcdonnell could you confirm this?

@csoneson would this then be enough to accept the submission for publication?

csoneson commented 2 years ago

Thanks all - it would be great to have a confirmation that the unit tests indeed pass (either from @marshallmcdonnell, or if you can point us to where to look in the GitHub Actions if it's there). If possible, it would also be great if @chryswoods would be able to tick the remaining boxes in the checklist above before we move on.

hechth commented 2 years ago

@csoneson @chryswoods I re-ran all tests manually and they all pass (and are actually run), as well as on the CI - see here.

See the log output beneath for more information:

Running tests (pytest): c:\Users\473355\git\recetox\MSMetaEnhancer
Running test with arguments: --rootdir c:\Users\473355\git\recetox\MSMetaEnhancer --override-ini junit_family=xunit1 --junit-xml=C:\Temp\tmp-19804OKRM7VSNOeyQ.xml
Current working directory: c:\Users\473355\git\recetox\MSMetaEnhancer
Workspace directory: c:\Users\473355\git\recetox\MSMetaEnhancer
Run completed, parsing output
./tests/test_BridgeDB.py::test_service_available Passed

./tests/test_BridgeDB.py::test_format Passed

./tests/test_BridgeDB.py::test_get_conversions Passed

./tests/test_CIR.py::test_service_available Passed

./tests/test_CIR.py::test_format Passed

./tests/test_CIR.py::test_get_conversions Passed

./tests/test_CTS.py::test_format[7783-89-3-1] Passed

./tests/test_CTS.py::test_format[7783893-0] Passed

./tests/test_CTS.py::test_service_available Passed

./tests/test_CTS.py::test_get_conversions Passed

./tests/test_IDSM.py::test_service_available Passed

./tests/test_IDSM.py::test_format Passed

./tests/test_IDSM.py::test_get_conversions Passed

./tests/test_NLM.py::test_service_available Passed

./tests/test_NLM.py::test_format Passed

./tests/test_NLM.py::test_get_conversions Passed

./tests/test_PubChem.py::test_parse_attributes[response0-expected0] Passed

./tests/test_PubChem.py::test_parse_attributes[response1-expected1] Passed

./tests/test_PubChem.py::test_service_available Passed

./tests/test_PubChem.py::test_format Passed

./tests/test_PubChem.py::test_get_conversions Passed

./tests/test_annotator.py::test_annotate[data0-expected0-False-mocked0] Passed

./tests/test_annotator.py::test_annotate[data1-expected1-True-mocked1] Passed

./tests/test_annotator.py::test_execute_job_with_cache Passed

./tests/test_annotator.py::test_catch_exception Passed

./tests/test_application.py::test_annotate_spectra_monitor_stops Passed

./tests/test_application.py::test_annotate_spectra_monitor_stops_after_exception Passed

./tests/test_converter.py::test_loop_request_circuit_breaker_get[TimeoutError] Passed

./tests/test_converter.py::test_loop_request_circuit_breaker_get[ServerDisconnectedError] Passed

./tests/test_converter.py::test_loop_request_circuit_breaker_get[failing_session_mock2] Passed

./tests/test_converter.py::test_loop_request_circuit_breaker_post[TimeoutError] Passed

./tests/test_converter.py::test_loop_request_circuit_breaker_post[ServerDisconnectedError] Passed

./tests/test_converter.py::test_loop_request_circuit_breaker_post[failing_session_mock2] Passed

./tests/test_converter.py::test_process_request_exception[False-500] Passed

./tests/test_converter.py::test_process_request_exception[False-503] Passed

./tests/test_converter.py::test_query_the_service Passed

./tests/test_converter.py::test_loop_request Passed

./tests/test_converter.py::test_loop_request_fail Passed

./tests/test_converter.py::test_process_request Passed

./tests/test_converter.py::test_convert Passed

./tests/test_converter.py::test_lru_cache Passed

./tests/test_curator.py::test_filter_invalid_metadata[metadata0-validated_metadata0-1] Passed

./tests/test_curator.py::test_filter_invalid_metadata[metadata1-validated_metadata1-0] Passed

./tests/test_curator.py::test_fix_cas_number Passed

Total number of tests expected to run: 44
Total number of tests run: 44
Total number of tests passed: 44
Total number of tests failed: 0
Total number of tests failed with errors: 0
Total number of tests skipped: 0
Total number of tests with no result data: 0
Finished running tests!

> Test run finished at 28/09/2022, 17:28:38 <
csoneson commented 1 year ago

πŸ‘‹πŸ» @hechth - apologies for the delay. I checked the tests and they look good to me. Hence, based on @chryswoods comment, I have checked the remaining boxes in the review checklist, and will proceed with the next steps. I will take a look through the submission, and get back to you shortly.

csoneson commented 1 year ago

@editorialbot generate pdf

editorialbot commented 1 year ago

:point_right::page_facing_up: Download article proof :page_facing_up: View article proof on GitHub :page_facing_up: :point_left:

csoneson commented 1 year ago

@editorialbot check references

editorialbot commented 1 year ago
Reference check summary (note 'MISSING' DOIs are suggestions that need verification):

OK DOIs

- 10.1101/2021.02.28.433248 is OK
- 10.21105/joss.02411 is OK
- 10.1093/bioinformatics/btq476 is OK
- 10.1300/j115v21n01_04 is OK
- 10.1093/nar/gkaa971 is OK
- 10.1093/bioinformatics/btn307 is OK
- 10.1093/nar/gky379 is OK
- 10.1038/s41592-018-0046-7 is OK
- 10.1186/s13321-021-00515-1 is OK
- 10.5281/zenodo.6035335 is OK
- 10.1093/nar/gkab1062 is OK
- 10.1186/1471-2105-11-5 is OK
- 10.3390/metabo8010016 is OK
- 10.3897/rio.8.e83031 is OK
- 10.3389/fpubh.2021.622558 is OK
- 10.1007/s13361-016-1589-4 is OK
- 10.1016/S1044-0305(98)00159-7 is OK
- 10.1002/jms.3131 is OK

MISSING DOIs

- None

INVALID DOIs

- None
csoneson commented 1 year ago

@hechth Alright, I went through the submission as well and overall it looks great - I opened a PR with a couple of minor fixes to the bibliography: https://github.com/RECETOX/MSMetaEnhancer/pull/128 Please take a look and merge if you agree. Is there a way to provide a DOI/URL for RDKit?

The next steps then are as follows:

I can then move forward with accepting the submission.

hechth commented 1 year ago

@editorialbot generate pdf

editorialbot commented 1 year ago

:point_right::page_facing_up: Download article proof :page_facing_up: View article proof on GitHub :page_facing_up: :point_left:

hechth commented 1 year ago

@editorialbot check references

editorialbot commented 1 year ago
Reference check summary (note 'MISSING' DOIs are suggestions that need verification):

OK DOIs

- 10.1101/2021.02.28.433248 is OK
- 10.21105/joss.02411 is OK
- 10.1093/bioinformatics/btq476 is OK
- 10.1300/j115v21n01_04 is OK
- 10.1093/nar/gkaa971 is OK
- 10.1093/bioinformatics/btn307 is OK
- 10.18637/jss.v093.i13 is OK
- 10.1093/nar/gky379 is OK
- 10.1038/s41592-018-0046-7 is OK
- 10.1186/s13321-021-00515-1 is OK
- 10.5281/zenodo.6035335 is OK
- 10.1093/nar/gkab1062 is OK
- 10.1186/1471-2105-11-5 is OK
- 10.3390/metabo8010016 is OK
- 10.3897/rio.8.e83031 is OK
- 10.3389/fpubh.2021.622558 is OK
- 10.1007/s13361-016-1589-4 is OK
- 10.1016/S1044-0305(98)00159-7 is OK
- 10.1002/jms.3131 is OK
- 10.5281/zenodo.6961488 is OK

MISSING DOIs

- None

INVALID DOIs

- None
hechth commented 1 year ago

@csoneson I made a new release 0.2.5 with tag v0.2.5 which is archived on Zenodo with DOI: 10.5281/zenodo.7211726 at https://zenodo.org/record/7211726

csoneson commented 1 year ago

@editorialbot set 10.5281/zenodo.7211726 as archive

editorialbot commented 1 year ago

Done! Archive is now 10.5281/zenodo.7211726