Warning: Permanently added '3.90.35.235' (ED25519) to the list of known hosts. You can reproduce this build on your computer by running: sudo dnf install copr-rpmbuild /usr/bin/copr-rpmbuild --verbose --drop-resultdir --task-url https://copr.fedorainfracloud.org/backend/get-build-task/11200695-fedora-44-aarch64 --chroot fedora-44-aarch64 Version: 1.10 PID: 15422 Logging PID: 15424 Task: {'allow_user_ssh': False, 'appstream': False, 'background': False, 'build_id': 11200695, 'buildroot_pkgs': [], 'chroot': 'fedora-44-aarch64', 'enable_net': False, 'fedora_review': False, 'git_hash': 'b8a12e4556de21de570cf253073fba29bf0b3a85', 'git_repo': 'https://copr-dist-git.fedorainfracloud.org/git/mhough/biofedora/python-sbmlutils', 'isolation': 'default', 'memory_reqs': 2048, 'package_name': 'python-sbmlutils', 'package_version': '0.17.0-1', 'project_dirname': 'biofedora', 'project_name': 'biofedora', 'project_owner': 'mhough', 'repo_priority': None, 'repos': [{'baseurl': 'https://download.copr.fedorainfracloud.org/results/mhough/biofedora/fedora-44-aarch64/', 'id': 'copr_base', 'name': 'Copr repository', 'priority': None, 'repo_gpgcheck': False}, {'baseurl': 'https://download.copr.fedorainfracloud.org/results/mhough/neurofedora/fedora-44-aarch64/', 'id': 'copr_mhough_neurofedora', 'name': 'Additional repo copr_mhough_neurofedora', 'repo_gpgcheck': False}], 'sandbox': 'mhough/biofedora--mhough', 'source_json': {}, 'source_type': None, 'ssh_public_keys': None, 'storage': 1, 'submitter': 'mhough', 'tags': [], 'task_id': '11200695-fedora-44-aarch64', 'timeout': 18000, 'uses_devel_repo': False, 'with_opts': [], 'without_opts': []} Running: git clone https://copr-dist-git.fedorainfracloud.org/git/mhough/biofedora/python-sbmlutils /var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils --depth 500 --no-single-branch --recursive cmd: ['git', 'clone', 'https://copr-dist-git.fedorainfracloud.org/git/mhough/biofedora/python-sbmlutils', '/var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils', '--depth', '500', '--no-single-branch', '--recursive'] cwd: . rc: 0 stdout: stderr: Cloning into '/var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils'... Running: git checkout b8a12e4556de21de570cf253073fba29bf0b3a85 -- cmd: ['git', 'checkout', 'b8a12e4556de21de570cf253073fba29bf0b3a85', '--'] cwd: /var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils rc: 0 stdout: stderr: Note: switching to 'b8a12e4556de21de570cf253073fba29bf0b3a85'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at b8a12e4 automatic import of python-sbmlutils Running: dist-git-client sources cmd: ['dist-git-client', 'sources'] cwd: /var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils rc: 0 stdout: stderr: INFO: Reading stdout from command: git rev-parse --abbrev-ref HEAD INFO: Reading stdout from command: git rev-parse HEAD INFO: Reading sources specification file: sources INFO: Downloading sbmlutils-0.17.0.tar.gz INFO: Reading stdout from command: curl --help all INFO: Calling: curl -H Pragma: -H 'Accept-Encoding: identity' -o sbmlutils-0.17.0.tar.gz --location --connect-timeout 60 --retry 3 --retry-delay 10 --remote-time --show-error --fail --retry-all-errors https://copr-dist-git.fedorainfracloud.org/repo/pkgs/mhough/biofedora/python-sbmlutils/sbmlutils-0.17.0.tar.gz/md5/09507bedac253cc7ee879224133ff772/sbmlutils-0.17.0.tar.gz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3.57M 100 3.57M 0 0 176.3M 0 0 INFO: Reading stdout from command: md5sum sbmlutils-0.17.0.tar.gz tail: /var/lib/copr-rpmbuild/main.log: file truncated Running (timeout=18000): unbuffer mock --spec /var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils/python-sbmlutils.spec --sources /var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils --resultdir /var/lib/copr-rpmbuild/results --uniqueext 1792824741.766395 -r /var/lib/copr-rpmbuild/results/configs/child.cfg INFO: mock.py version 6.9 starting (python version = 3.14.5, NVR = mock-6.9-1.fc44), args: /usr/libexec/mock/mock --spec /var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils/python-sbmlutils.spec --sources /var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils --resultdir /var/lib/copr-rpmbuild/results --uniqueext 1792824741.766395 -r /var/lib/copr-rpmbuild/results/configs/child.cfg Start(bootstrap): init plugins INFO: tmpfs initialized INFO: selinux enabled INFO: chroot_scan: initialized INFO: compress_logs: initialized Finish(bootstrap): init plugins Start: init plugins INFO: tmpfs initialized INFO: selinux enabled INFO: chroot_scan: initialized INFO: compress_logs: initialized Finish: init plugins INFO: Signal handler active Start: run INFO: Start(/var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils/python-sbmlutils.spec) Config(fedora-44-aarch64) Start: clean chroot Finish: clean chroot Mock Version: 6.9 INFO: Mock Version: 6.9 Start(bootstrap): chroot init INFO: mounting tmpfs at /var/lib/mock/fedora-44-aarch64-bootstrap-1792824741.766395/root. INFO: calling preinit hooks INFO: enabled root cache INFO: enabled package manager cache Start(bootstrap): cleaning package manager metadata Finish(bootstrap): cleaning package manager metadata INFO: Guessed host environment type: unknown INFO: Using container image: registry.fedoraproject.org/fedora:44 INFO: Pulling image: registry.fedoraproject.org/fedora:44 INFO: Tagging container image as mock-bootstrap-b28135d6-e992-4c4d-a148-35b57a1ef02c INFO: Checking that b7e5ccd4fe73ede1c962d6e51e3d9362cc7573b1f88e56c0c7f02ffb1b4bb05e image matches host's architecture INFO: Copy content of container b7e5ccd4fe73ede1c962d6e51e3d9362cc7573b1f88e56c0c7f02ffb1b4bb05e to /var/lib/mock/fedora-44-aarch64-bootstrap-1792824741.766395/root INFO: mounting b7e5ccd4fe73ede1c962d6e51e3d9362cc7573b1f88e56c0c7f02ffb1b4bb05e with podman image mount INFO: image b7e5ccd4fe73ede1c962d6e51e3d9362cc7573b1f88e56c0c7f02ffb1b4bb05e as /var/lib/containers/storage/overlay/6575fb2d236d0b44599a46c0a5c07e66c7a8828b7f3ddc7839c1de9101a7b98a/merged INFO: umounting image b7e5ccd4fe73ede1c962d6e51e3d9362cc7573b1f88e56c0c7f02ffb1b4bb05e (/var/lib/containers/storage/overlay/6575fb2d236d0b44599a46c0a5c07e66c7a8828b7f3ddc7839c1de9101a7b98a/merged) with podman image umount INFO: Removing image mock-bootstrap-b28135d6-e992-4c4d-a148-35b57a1ef02c INFO: Package manager dnf5 detected and used (fallback) INFO: Not updating bootstrap chroot, bootstrap_image_ready=True Start(bootstrap): creating root cache Finish(bootstrap): creating root cache Finish(bootstrap): chroot init Start: chroot init INFO: mounting tmpfs at /var/lib/mock/fedora-44-aarch64-1792824741.766395/root. INFO: calling preinit hooks INFO: enabled root cache INFO: enabled package manager cache Start: cleaning package manager metadata Finish: cleaning package manager metadata INFO: enabled HW Info plugin INFO: Package manager dnf5 detected and used (direct choice) INFO: Buildroot is handled by package management downloaded with a bootstrap image: rpm-6.0.2-1.fc44.aarch64 rpm-sequoia-1.10.3-1.fc44.aarch64 dnf5-5.4.6.0-1.fc44.aarch64 dnf5-plugins-5.4.6.0-1.fc44.aarch64 Start: installing minimal buildroot with dnf5 Updating and loading repositories: updates 100% | 28.6 KiB/s | 9.8 KiB | 00m00s fedora 100% | 29.6 KiB/s | 10.2 KiB | 00m00s Additional repo copr_mhough_neurofedor 100% | 5.3 KiB/s | 1.5 KiB | 00m00s Copr repository 100% | 5.3 KiB/s | 1.5 KiB | 00m00s Repositories loaded. Package Arch Version Repository Size Installing group/module packages: bash aarch64 0:5.3.9-3.fc44 fedora 8.4 MiB bzip2 aarch64 0:1.0.8-23.fc44 fedora 171.1 KiB coreutils aarch64 0:9.10-5.fc44 updates 8.2 MiB cpio aarch64 0:2.15-9.fc44 fedora 1.1 MiB diffutils aarch64 0:3.12-5.fc44 fedora 1.6 MiB fedora-release-common noarch 0:44-18 updates 20.6 KiB findutils aarch64 1:4.10.0-7.fc44 fedora 1.9 MiB gawk aarch64 0:5.3.2-3.fc44 fedora 2.6 MiB glibc-minimal-langpack aarch64 0:2.43-9.fc44 updates 0.0 B grep aarch64 0:3.12-3.fc44 fedora 1.0 MiB gzip aarch64 0:1.14-2.fc44 fedora 437.5 KiB info aarch64 0:7.2-9.fc44 fedora 421.5 KiB patch aarch64 0:2.8-4.fc44 fedora 262.4 KiB redhat-rpm-config noarch 0:344-2.fc44 updates 183.7 KiB rpm-build aarch64 0:6.0.2-1.fc44 updates 598.7 KiB sed aarch64 0:4.9-7.fc44 fedora 873.1 KiB shadow-utils aarch64 2:4.19.0-7.fc44 updates 4.4 MiB tar aarch64 2:1.35-9.fc44 updates 3.0 MiB unzip aarch64 0:6.0-69.fc44 fedora 533.8 KiB util-linux aarch64 0:2.41.5-1.fc44 updates 6.8 MiB which aarch64 0:2.25-1.fc44 updates 123.6 KiB xz aarch64 1:5.8.2-2.fc44 fedora 1.4 MiB Installing dependencies: R-srpm-macros noarch 0:1.3.7-2.fc44 updates 3.5 KiB add-determinism aarch64 0:0.7.3-2.fc44 updates 2.0 MiB alternatives aarch64 0:1.33-5.fc44 fedora 90.1 KiB ansible-srpm-macros noarch 0:1-20.1.fc44 fedora 35.7 KiB audit-libs aarch64 0:4.2.1-1.fc44 updates 486.7 KiB binutils aarch64 0:2.46.1-1.fc44 updates 31.5 MiB build-reproducibility-srpm-macros noarch 0:0.7.3-2.fc44 updates 1.2 KiB bzip2-libs aarch64 0:1.0.8-23.fc44 fedora 72.5 KiB ca-certificates noarch 0:2026.2.92_v9.0.319-2.fc44 updates 2.7 MiB cmake-srpm-macros noarch 0:4.3.0-1.fc44 fedora 524.0 B coreutils-common aarch64 0:9.10-5.fc44 updates 10.7 MiB crypto-policies noarch 0:20251128-3.git19878fe.fc44 fedora 132.6 KiB curl aarch64 0:8.18.0-14.fc44 updates 464.2 KiB cyrus-sasl-lib aarch64 0:2.1.28-35.fc44 fedora 2.4 MiB debugedit aarch64 0:5.3-2.fc44 updates 320.9 KiB dwz aarch64 0:0.16-3.fc44 fedora 322.4 KiB ed aarch64 0:1.22.5-2.fc44 fedora 157.8 KiB efi-srpm-macros noarch 0:6-6.fc44 fedora 40.2 KiB elfutils aarch64 0:0.196-1.fc44 updates 3.8 MiB elfutils-debuginfod-client aarch64 0:0.196-1.fc44 updates 144.0 KiB elfutils-default-yama-scope noarch 0:0.196-1.fc44 updates 1.8 KiB elfutils-libelf aarch64 0:0.196-1.fc44 updates 1.5 MiB elfutils-libs aarch64 0:0.196-1.fc44 updates 746.6 KiB erlang-srpm-macros noarch 0:0.4.0-1.fc44 updates 2.0 KiB fedora-gpg-keys noarch 0:44-2 updates 257.6 KiB fedora-release noarch 0:44-18 updates 0.0 B fedora-release-identity-basic noarch 0:44-18 updates 629.0 B fedora-repos noarch 0:44-2 updates 4.9 KiB file aarch64 0:5.46-10.fc44 updates 140.1 KiB file-libs aarch64 0:5.46-10.fc44 updates 11.9 MiB filesystem aarch64 0:3.18-52.fc44 fedora 112.0 B filesystem-srpm-macros noarch 0:3.18-52.fc44 fedora 38.2 KiB fonts-srpm-macros noarch 1:5.0.0-2.fc44 fedora 55.8 KiB forge-srpm-macros noarch 0:0.4.0-4.fc44 fedora 38.9 KiB fpc-srpm-macros noarch 0:1.3-16.fc44 fedora 144.0 B gap-srpm-macros noarch 0:2-2.fc44 fedora 2.1 KiB gdb-minimal aarch64 0:17.2-4.fc44 updates 13.5 MiB gdbm-libs aarch64 1:1.23-11.fc44 fedora 233.7 KiB ghc-srpm-macros noarch 0:1.10-1.fc44 fedora 792.0 B glibc aarch64 0:2.43-9.fc44 updates 6.4 MiB glibc-common aarch64 0:2.43-9.fc44 updates 1.3 MiB glibc-gconv-extra aarch64 0:2.43-9.fc44 updates 18.5 MiB gmp aarch64 1:6.3.0-5.fc44 fedora 657.9 KiB gnat-srpm-macros noarch 0:7-2.fc44 fedora 1.0 KiB gnome-srpm-macros noarch 0:1.0-1.fc44 updates 3.5 KiB gnulib-l10n noarch 0:20241231-2.fc44 fedora 655.0 KiB gnupg2 aarch64 0:2.4.9-16.fc44 updates 6.4 MiB gnupg2-dirmngr aarch64 0:2.4.9-16.fc44 updates 646.1 KiB gnupg2-gpg-agent aarch64 0:2.4.9-16.fc44 updates 846.9 KiB gnupg2-gpgconf aarch64 0:2.4.9-16.fc44 updates 321.8 KiB gnupg2-keyboxd aarch64 0:2.4.9-16.fc44 updates 233.3 KiB gnupg2-verify aarch64 0:2.4.9-16.fc44 updates 364.3 KiB gnutls aarch64 0:3.8.13-1.fc44 updates 3.7 MiB go-srpm-macros noarch 0:3.8.0-2.fc44 fedora 61.9 KiB gpgverify noarch 0:2.2-4.fc44 fedora 8.7 KiB ima-evm-utils-libs aarch64 0:1.6.2-8.fc44 fedora 92.6 KiB jansson aarch64 0:2.14-4.fc44 fedora 93.0 KiB java-srpm-macros noarch 0:1-8.fc44 fedora 870.0 B json-c aarch64 0:0.18-8.fc44 fedora 138.5 KiB kernel-srpm-macros noarch 0:1.0-28.fc44 fedora 1.9 KiB keyutils-libs aarch64 0:1.6.3-7.fc44 fedora 98.2 KiB krb5-libs aarch64 0:1.22.2-4.fc44 updates 2.5 MiB libacl aarch64 0:2.4.0-1.fc44 updates 67.9 KiB libarchive aarch64 0:3.8.7-1.fc44 updates 975.5 KiB libassuan aarch64 0:2.5.7-5.fc44 fedora 215.8 KiB libattr aarch64 0:2.6.0-1.fc44 updates 68.4 KiB libblkid aarch64 0:2.41.5-1.fc44 updates 290.4 KiB libbrotli aarch64 0:1.2.0-3.fc44 fedora 909.1 KiB libcap aarch64 0:2.78-1.fc44 updates 508.4 KiB libcap-ng aarch64 0:0.9.6-1.fc44 updates 160.9 KiB libcbor aarch64 0:0.13.0-2.fc44 fedora 139.5 KiB libcom_err aarch64 0:1.47.3-4.fc44 fedora 111.0 KiB libcurl aarch64 0:8.18.0-14.fc44 updates 980.9 KiB libeconf aarch64 0:0.7.9-3.fc44 fedora 80.8 KiB libevent aarch64 0:2.1.13-1.fc44 updates 1.1 MiB libfdisk aarch64 0:2.41.5-1.fc44 updates 418.8 KiB libffi aarch64 0:3.5.2-2.fc44 fedora 155.7 KiB libfido2 aarch64 0:1.16.0-5.fc44 fedora 278.6 KiB libfsverity aarch64 0:1.6-4.fc44 fedora 68.4 KiB libgcc aarch64 0:16.2.1-2.fc44 updates 222.3 KiB libgcrypt aarch64 0:1.12.2-1.fc44 updates 1.2 MiB libgomp aarch64 0:16.2.1-2.fc44 updates 592.9 KiB libgpg-error aarch64 0:1.58-2.fc44 fedora 989.6 KiB libidn2 aarch64 0:2.3.8-3.fc44 fedora 560.4 KiB libksba aarch64 0:1.6.7-5.fc44 fedora 398.3 KiB liblastlog2 aarch64 0:2.41.5-1.fc44 updates 137.8 KiB libmount aarch64 0:2.41.5-1.fc44 updates 420.2 KiB libnghttp2 aarch64 0:1.68.0-5.fc44 updates 197.9 KiB libnghttp3 aarch64 0:1.18.0-1.fc44 updates 206.8 KiB libpfm aarch64 0:4.13.0-20.fc44 updates 251.9 KiB libpkgconf aarch64 0:2.5.1-1.fc44 fedora 134.1 KiB libpsl aarch64 0:0.21.5-7.fc44 fedora 132.3 KiB libselinux aarch64 0:3.11-2.fc44 updates 265.2 KiB libselinux-utils aarch64 0:3.11-2.fc44 updates 1.3 MiB libsemanage aarch64 0:3.11-1.fc44 updates 360.1 KiB libsepol aarch64 0:3.11-1.fc44 updates 809.9 KiB libsmartcols aarch64 0:2.41.5-1.fc44 updates 224.4 KiB libssh aarch64 0:0.12.2-1.fc44 updates 721.3 KiB libssh-config noarch 0:0.12.2-1.fc44 updates 277.0 B libstdc++ aarch64 0:16.2.1-2.fc44 updates 3.0 MiB libtasn1 aarch64 0:4.21.0-1.fc44 fedora 220.7 KiB libtool-ltdl aarch64 0:2.5.4-10.fc44 fedora 93.9 KiB libunistring aarch64 0:1.1-11.fc44 fedora 1.7 MiB libusb1 aarch64 0:1.0.30-1.fc44 updates 179.7 KiB libuuid aarch64 0:2.41.5-1.fc44 updates 69.3 KiB libverto aarch64 0:0.3.2-12.fc44 fedora 69.3 KiB libxcrypt aarch64 0:4.5.2-3.fc44 fedora 273.2 KiB libxml2 aarch64 0:2.12.10-6.fc44 fedora 1.9 MiB libzstd aarch64 0:1.5.7-5.fc44 fedora 860.2 KiB linkdupes aarch64 0:0.7.3-2.fc44 updates 713.7 KiB lua-libs aarch64 0:5.4.8-5.fc44 fedora 329.8 KiB lua-srpm-macros noarch 0:1-17.fc44 fedora 1.3 KiB lz4-libs aarch64 0:1.10.0-4.fc44 fedora 197.3 KiB mpfr aarch64 0:4.2.2-3.fc44 fedora 755.4 KiB ncurses-base noarch 0:6.6-1.fc44 fedora 329.7 KiB ncurses-libs aarch64 0:6.6-1.fc44 fedora 1.2 MiB nettle aarch64 0:3.10.1-3.fc44 fedora 765.0 KiB ngtcp2 aarch64 0:1.22.1-1.fc44 updates 341.1 KiB ngtcp2-crypto-ossl aarch64 0:1.22.1-1.fc44 updates 67.5 KiB npth aarch64 0:1.8-4.fc44 fedora 93.3 KiB ocaml-srpm-macros noarch 0:11-3.fc44 fedora 1.9 KiB openblas-srpm-macros noarch 0:2-21.fc44 fedora 112.0 B openldap aarch64 0:2.6.15-1.fc44 updates 765.6 KiB openssl-libs aarch64 1:3.5.9-1.fc44 updates 7.5 MiB p11-kit aarch64 0:0.26.5-1.fc44 updates 2.8 MiB p11-kit-trust aarch64 0:0.26.5-1.fc44 updates 530.1 KiB package-notes-srpm-macros noarch 0:0.20-1.fc44 updates 1.6 KiB pam-libs aarch64 0:1.7.2-2.fc44 updates 222.7 KiB pcre2 aarch64 0:10.47-1.fc44.1 fedora 714.3 KiB pcre2-syntax noarch 0:10.47-1.fc44.1 fedora 281.9 KiB perl-srpm-macros noarch 0:1-61.fc44 fedora 861.0 B pkgconf aarch64 0:2.5.1-1.fc44 fedora 116.8 KiB pkgconf-m4 noarch 0:2.5.1-1.fc44 fedora 14.3 KiB pkgconf-pkg-config aarch64 0:2.5.1-1.fc44 fedora 990.0 B policycoreutils aarch64 0:3.11-2.fc44 updates 1.5 MiB popt aarch64 0:1.19-10.fc44 fedora 144.6 KiB publicsuffix-list-dafsa noarch 0:20260116-1.fc44 fedora 70.4 KiB pyproject-srpm-macros noarch 0:1.24.0-1.fc44 updates 3.4 KiB python-srpm-macros noarch 0:3.14-12.fc44 fedora 51.6 KiB qt5-srpm-macros noarch 0:5.15.18-2.fc44 fedora 500.0 B qt6-srpm-macros noarch 0:6.11.2-1.fc44 updates 472.0 B readline aarch64 0:8.3-4.fc44 fedora 563.5 KiB rpm aarch64 0:6.0.2-1.fc44 updates 3.3 MiB rpm-build-libs aarch64 0:6.0.2-1.fc44 updates 264.1 KiB rpm-libs aarch64 0:6.0.2-1.fc44 updates 995.2 KiB rpm-plugin-selinux aarch64 0:6.0.2-1.fc44 updates 67.9 KiB rpm-sequoia aarch64 0:1.10.3-1.fc44 updates 2.3 MiB rpm-sign-libs aarch64 0:6.0.2-1.fc44 updates 67.7 KiB rust-srpm-macros noarch 0:28.5-1.fc44 updates 5.5 KiB selinux-policy noarch 0:44.11-1.fc44 updates 32.1 KiB selinux-policy-targeted noarch 0:44.11-1.fc44 updates 18.6 MiB setup noarch 0:2.15.0-28.fc44 fedora 724.9 KiB sqlite-libs aarch64 0:3.51.2-2.fc44 updates 1.6 MiB systemd-libs aarch64 0:259.10-1.fc44 updates 2.5 MiB systemd-standalone-sysusers aarch64 0:259.10-1.fc44 updates 329.6 KiB tpm2-tss aarch64 0:4.1.3-9.fc44 fedora 2.1 MiB tree-sitter-srpm-macros noarch 0:0.4.2-2.fc44 fedora 8.3 KiB util-linux-core aarch64 0:2.41.5-1.fc44 updates 2.4 MiB xxhash-libs aarch64 0:0.8.4-1.fc44 updates 85.8 KiB xz-libs aarch64 1:5.8.2-2.fc44 fedora 265.4 KiB zig-srpm-macros noarch 0:1-8.fc44 fedora 1.3 KiB zip aarch64 0:3.0-45.fc44 fedora 762.0 KiB zlib-ng-compat aarch64 0:2.3.3-3.fc44 fedora 133.4 KiB zstd aarch64 0:1.5.7-5.fc44 fedora 562.2 KiB Installing groups: Buildsystem building group Transaction Summary: Installing: 186 packages Total size of inbound packages is 67 MiB. Need to download 0 B. After this operation, 251 MiB extra will be used (install 251 MiB, remove 0 B). [ 1/186] bzip2-0:1.0.8-23.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 2/186] unzip-0:6.0-69.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 3/186] cpio-0:2.15-9.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 4/186] bash-0:5.3.9-3.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 5/186] grep-0:3.12-3.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 6/186] patch-0:2.8-4.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 7/186] sed-0:4.9-7.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 8/186] diffutils-0:3.12-5.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 9/186] findutils-1:4.10.0-7.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 10/186] gawk-0:5.3.2-3.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 11/186] gzip-0:1.14-2.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 12/186] info-0:7.2-9.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 13/186] xz-1:5.8.2-2.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 14/186] tar-2:1.35-9.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 15/186] redhat-rpm-config-0:344-2.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 16/186] rpm-build-0:6.0.2-1.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 17/186] which-0:2.25-1.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 18/186] coreutils-0:9.10-5.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 19/186] shadow-utils-2:4.19.0-7.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 20/186] util-linux-0:2.41.5-1.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 21/186] fedora-release-common-0:44-18 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 22/186] glibc-minimal-langpack-0:2.43 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 23/186] bzip2-libs-0:1.0.8-23.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 24/186] filesystem-0:3.18-52.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 25/186] ncurses-libs-0:6.6-1.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 26/186] pcre2-0:10.47-1.fc44.1.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 27/186] ed-0:1.22.5-2.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 28/186] gmp-1:6.3.0-5.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 29/186] mpfr-0:4.2.2-3.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 30/186] readline-0:8.3-4.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 31/186] xz-libs-1:5.8.2-2.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 32/186] gnome-srpm-macros-0:1.0-1.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 33/186] ansible-srpm-macros-0:1-20.1. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 34/186] cmake-srpm-macros-0:4.3.0-1.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 35/186] dwz-0:0.16-3.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 36/186] efi-srpm-macros-0:6-6.fc44.no 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 37/186] filesystem-srpm-macros-0:3.18 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 38/186] fonts-srpm-macros-1:5.0.0-2.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 39/186] forge-srpm-macros-0:0.4.0-4.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 40/186] fpc-srpm-macros-0:1.3-16.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 41/186] gap-srpm-macros-0:2-2.fc44.no 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 42/186] ghc-srpm-macros-0:1.10-1.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 43/186] gnat-srpm-macros-0:7-2.fc44.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 44/186] go-srpm-macros-0:3.8.0-2.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 45/186] java-srpm-macros-0:1-8.fc44.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 46/186] kernel-srpm-macros-0:1.0-28.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 47/186] lua-srpm-macros-0:1-17.fc44.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 48/186] ocaml-srpm-macros-0:11-3.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 49/186] openblas-srpm-macros-0:2-21.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 50/186] perl-srpm-macros-0:1-61.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 51/186] python-srpm-macros-0:3.14-12. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 52/186] qt5-srpm-macros-0:5.15.18-2.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 53/186] tree-sitter-srpm-macros-0:0.4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 54/186] zig-srpm-macros-0:1-8.fc44.no 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 55/186] zip-0:3.0-45.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 56/186] rpm-0:6.0.2-1.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 57/186] pkgconf-pkg-config-0:2.5.1-1. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 58/186] popt-0:1.19-10.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 59/186] zstd-0:1.5.7-5.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 60/186] coreutils-common-0:9.10-5.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 61/186] libeconf-0:0.7.9-3.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 62/186] libxcrypt-0:4.5.2-3.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 63/186] setup-0:2.15.0-28.fc44.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 64/186] libblkid-0:2.41.5-1.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 65/186] libfdisk-0:2.41.5-1.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 66/186] liblastlog2-0:2.41.5-1.fc44.a 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 67/186] libmount-0:2.41.5-1.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 68/186] libsmartcols-0:2.41.5-1.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 69/186] libuuid-0:2.41.5-1.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 70/186] util-linux-core-0:2.41.5-1.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 71/186] zlib-ng-compat-0:2.3.3-3.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 72/186] glibc-0:2.43-9.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 73/186] glibc-common-0:2.43-9.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 74/186] ncurses-base-0:6.6-1.fc44.noa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 75/186] pcre2-syntax-0:10.47-1.fc44.1 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 76/186] pkgconf-0:2.5.1-1.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 77/186] pkgconf-m4-0:2.5.1-1.fc44.noa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 78/186] libzstd-0:1.5.7-5.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 79/186] gnulib-l10n-0:20241231-2.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 80/186] glibc-gconv-extra-0:2.43-9.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 81/186] libpkgconf-0:2.5.1-1.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 82/186] rpm-libs-0:6.0.2-1.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 83/186] lua-libs-0:5.4.8-5.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 84/186] rpm-build-libs-0:6.0.2-1.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 85/186] rpm-sign-libs-0:6.0.2-1.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 86/186] ima-evm-utils-libs-0:1.6.2-8. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 87/186] libfsverity-0:1.6-4.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 88/186] tpm2-tss-0:4.1.3-9.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 89/186] json-c-0:0.18-8.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 90/186] libgcc-0:16.2.1-2.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 91/186] libstdc++-0:16.2.1-2.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 92/186] libusb1-0:1.0.30-1.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 93/186] openssl-libs-1:3.5.9-1.fc44.a 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 94/186] crypto-policies-0:20251128-3. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 95/186] libacl-0:2.4.0-1.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 96/186] libselinux-0:3.11-2.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 97/186] libsepol-0:3.11-1.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 98/186] libattr-0:2.6.0-1.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 99/186] elfutils-libelf-0:0.196-1.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [100/186] elfutils-libs-0:0.196-1.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [101/186] elfutils-0:0.196-1.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [102/186] elfutils-debuginfod-client-0: 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [103/186] systemd-libs-0:259.10-1.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [104/186] audit-libs-0:4.2.1-1.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [105/186] libcap-ng-0:0.9.6-1.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [106/186] pam-libs-0:1.7.2-2.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [107/186] libsemanage-0:3.11-1.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [108/186] gnupg2-0:2.4.9-16.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [109/186] gpgverify-0:2.2-4.fc44.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [110/186] gnupg2-dirmngr-0:2.4.9-16.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [111/186] gnupg2-gpg-agent-0:2.4.9-16.f 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [112/186] gnupg2-gpgconf-0:2.4.9-16.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [113/186] gnupg2-keyboxd-0:2.4.9-16.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [114/186] gnupg2-verify-0:2.4.9-16.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [115/186] libassuan-0:2.5.7-5.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [116/186] libgpg-error-0:1.58-2.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [117/186] npth-0:1.8-4.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [118/186] libksba-0:1.6.7-5.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [119/186] libcap-0:2.78-1.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [120/186] rpm-sequoia-0:1.10.3-1.fc44.a 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [121/186] sqlite-libs-0:3.51.2-2.fc44.a 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [122/186] file-libs-0:5.46-10.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [123/186] file-0:5.46-10.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [124/186] libgomp-0:16.2.1-2.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [125/186] binutils-0:2.46.1-1.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [126/186] alternatives-0:1.33-5.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [127/186] jansson-0:2.14-4.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [128/186] debugedit-0:5.3-2.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [129/186] libarchive-0:3.8.7-1.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [130/186] libxml2-0:2.12.10-6.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [131/186] lz4-libs-0:1.10.0-4.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [132/186] curl-0:8.18.0-14.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [133/186] R-srpm-macros-0:1.3.7-2.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [134/186] build-reproducibility-srpm-ma 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [135/186] add-determinism-0:0.7.3-2.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [136/186] linkdupes-0:0.7.3-2.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [137/186] erlang-srpm-macros-0:0.4.0-1. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [138/186] package-notes-srpm-macros-0:0 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [139/186] pyproject-srpm-macros-0:1.24. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [140/186] qt6-srpm-macros-0:6.11.2-1.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [141/186] rust-srpm-macros-0:28.5-1.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [142/186] ca-certificates-0:2026.2.92_v 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [143/186] libffi-0:3.5.2-2.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [144/186] libgcrypt-0:1.12.2-1.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [145/186] gnutls-0:3.8.13-1.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [146/186] libidn2-0:2.3.8-3.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [147/186] libtasn1-0:4.21.0-1.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [148/186] libunistring-0:1.1-11.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [149/186] nettle-0:3.10.1-3.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [150/186] openldap-0:2.6.15-1.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [151/186] cyrus-sasl-lib-0:2.1.28-35.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [152/186] libtool-ltdl-0:2.5.4-10.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [153/186] gdbm-libs-1:1.23-11.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [154/186] fedora-repos-0:44-2.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [155/186] fedora-gpg-keys-0:44-2.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [156/186] elfutils-default-yama-scope-0 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [157/186] libpfm-0:4.13.0-20.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [158/186] p11-kit-0:0.26.5-1.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [159/186] p11-kit-trust-0:0.26.5-1.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [160/186] libevent-0:2.1.13-1.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [161/186] fedora-release-0:44-18.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [162/186] systemd-standalone-sysusers-0 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [163/186] gdb-minimal-0:17.2-4.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [164/186] xxhash-libs-0:0.8.4-1.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [165/186] fedora-release-identity-basic 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [166/186] libcurl-0:8.18.0-14.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [167/186] libnghttp3-0:1.18.0-1.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [168/186] libssh-0:0.12.2-1.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [169/186] ngtcp2-0:1.22.1-1.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [170/186] libbrotli-0:1.2.0-3.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [171/186] libpsl-0:0.21.5-7.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [172/186] libssh-config-0:0.12.2-1.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [173/186] libfido2-0:1.16.0-5.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [174/186] publicsuffix-list-dafsa-0:202 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [175/186] libcbor-0:0.13.0-2.fc44.aarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [176/186] ngtcp2-crypto-ossl-0:1.22.1-1 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [177/186] selinux-policy-targeted-0:44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [178/186] selinux-policy-0:44.11-1.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [179/186] rpm-plugin-selinux-0:6.0.2-1. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [180/186] policycoreutils-0:3.11-2.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [181/186] libselinux-utils-0:3.11-2.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [182/186] krb5-libs-0:1.22.2-4.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [183/186] keyutils-libs-0:1.6.3-7.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [184/186] libcom_err-0:1.47.3-4.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [185/186] libverto-0:0.3.2-12.fc44.aarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [186/186] libnghttp2-0:1.68.0-5.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded -------------------------------------------------------------------------------- [186/186] Total 100% | 0.0 B/s | 0.0 B | 00m00s Running transaction Importing OpenPGP key 0x6D9F90A6: UserID : "Fedora (44) " Fingerprint: 36F612DCF27F7D1A48A835E4DBFCF71C6D9F90A6 From : file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-44-primary The key was successfully imported. [ 1/188] Verify package files 100% | 768.0 B/s | 186.0 B | 00m00s [ 2/188] Prepare transaction 100% | 2.5 KiB/s | 186.0 B | 00m00s [ 3/188] Installing libgcc-0:16.2.1-2. 100% | 218.7 MiB/s | 224.0 KiB | 00m00s [ 4/188] Installing publicsuffix-list- 100% | 69.4 MiB/s | 71.1 KiB | 00m00s [ 5/188] Installing libssh-config-0:0. 100% | 0.0 B/s | 816.0 B | 00m00s [ 6/188] Installing fedora-release-ide 100% | 867.2 KiB/s | 888.0 B | 00m00s [ 7/188] Installing fedora-gpg-keys-0: 100% | 34.7 MiB/s | 355.3 KiB | 00m00s [ 8/188] Installing fedora-repos-0:44- 100% | 0.0 B/s | 5.7 KiB | 00m00s [ 9/188] Installing fedora-release-com 100% | 24.3 MiB/s | 24.9 KiB | 00m00s [ 10/188] Installing fedora-release-0:4 100% | 20.2 KiB/s | 124.0 B | 00m00s >>> Running sysusers scriptlet: setup-0:2.15.0-28.fc44.noarch >>> Finished sysusers scriptlet: setup-0:2.15.0-28.fc44.noarch >>> Scriptlet output: >>> Creating group 'adm' with GID 4. >>> Creating group 'audio' with GID 63. >>> Creating group 'cdrom' with GID 11. >>> Creating group 'clock' with GID 103. >>> Creating group 'dialout' with GID 18. >>> Creating group 'disk' with GID 6. >>> Creating group 'floppy' with GID 19. >>> Creating group 'ftp' with GID 50. >>> Creating group 'games' with GID 20. >>> Creating group 'input' with GID 104. >>> Creating group 'kmem' with GID 9. >>> Creating group 'kvm' with GID 36. >>> Creating group 'lock' with GID 54. >>> Creating group 'lp' with GID 7. >>> Creating group 'mail' with GID 12. >>> Creating group 'man' with GID 15. >>> Creating group 'mem' with GID 8. >>> Creating group 'nobody' with GID 65534. >>> Creating group 'render' with GID 105. >>> Creating group 'root' with GID 0. >>> Creating group 'sgx' with GID 106. >>> Creating group 'sys' with GID 3. >>> Creating group 'tape' with GID 33. >>> Creating group 'tty' with GID 5. >>> Creating group 'users' with GID 100. >>> Creating group 'utmp' with GID 22. >>> Creating group 'video' with GID 39. >>> Creating group 'wheel' with GID 10. >>> Creating user 'adm' (adm) with UID 3 and GID 4. >>> Creating group 'bin' with GID 1. >>> Creating user 'bin' (bin) with UID 1 and GID 1. >>> Creating group 'daemon' with GID 2. >>> Creating user 'daemon' (daemon) with UID 2 and GID 2. >>> Creating user 'ftp' (FTP User) with UID 14 and GID 50. >>> Creating user 'games' (games) with UID 12 and GID 100. >>> Creating user 'halt' (halt) with UID 7 and GID 0. >>> Creating user 'lp' (lp) with UID 4 and GID 7. >>> Creating user 'mail' (mail) with UID 8 and GID 12. >>> Creating user 'nobody' (Kernel Overflow User) with UID 65534 and GID 65534. >>> Creating user 'operator' (operator) with UID 11 and GID 0. >>> Creating user 'root' (Super User) with UID 0 and GID 0. >>> Creating user 'shutdown' (shutdown) with UID 6 and GID 0. >>> Creating user 'sync' (sync) with UID 5 and GID 0. >>> [ 11/188] Installing setup-0:2.15.0-28. 100% | 39.6 MiB/s | 730.6 KiB | 00m00s >>> [RPM] /etc/hosts created as /etc/hosts.rpmnew [ 12/188] Installing filesystem-0:3.18- 100% | 2.0 MiB/s | 212.8 KiB | 00m00s [ 13/188] Installing rust-srpm-macros-0 100% | 6.2 MiB/s | 6.4 KiB | 00m00s [ 14/188] Installing qt6-srpm-macros-0: 100% | 0.0 B/s | 748.0 B | 00m00s [ 15/188] Installing package-notes-srpm 100% | 0.0 B/s | 2.1 KiB | 00m00s [ 16/188] Installing gnulib-l10n-0:2024 100% | 129.3 MiB/s | 661.9 KiB | 00m00s [ 17/188] Installing coreutils-common-0 100% | 323.8 MiB/s | 10.7 MiB | 00m00s [ 18/188] Installing pkgconf-m4-0:2.5.1 100% | 0.0 B/s | 14.7 KiB | 00m00s [ 19/188] Installing pcre2-syntax-0:10. 100% | 138.8 MiB/s | 284.3 KiB | 00m00s [ 20/188] Installing ncurses-base-0:6.6 100% | 57.8 MiB/s | 355.3 KiB | 00m00s [ 21/188] Installing bash-0:5.3.9-3.fc4 100% | 221.9 MiB/s | 8.4 MiB | 00m00s [ 22/188] Installing glibc-common-0:2.4 100% | 60.2 MiB/s | 1.3 MiB | 00m00s [ 23/188] Installing glibc-gconv-extra- 100% | 405.2 MiB/s | 18.6 MiB | 00m00s [ 24/188] Installing glibc-0:2.43-9.fc4 100% | 152.0 MiB/s | 6.4 MiB | 00m00s [ 25/188] Installing ncurses-libs-0:6.6 100% | 249.2 MiB/s | 1.2 MiB | 00m00s [ 26/188] Installing glibc-minimal-lang 100% | 0.0 B/s | 124.0 B | 00m00s [ 27/188] Installing zlib-ng-compat-0:2 100% | 131.1 MiB/s | 134.2 KiB | 00m00s [ 28/188] Installing bzip2-libs-0:1.0.8 100% | 71.9 MiB/s | 73.6 KiB | 00m00s [ 29/188] Installing libgpg-error-0:1.5 100% | 48.6 MiB/s | 995.5 KiB | 00m00s [ 30/188] Installing libstdc++-0:16.2.1 100% | 330.1 MiB/s | 3.0 MiB | 00m00s [ 31/188] Installing libassuan-0:2.5.7- 100% | 212.6 MiB/s | 217.7 KiB | 00m00s [ 32/188] Installing libgcrypt-0:1.12.2 100% | 300.0 MiB/s | 1.2 MiB | 00m00s [ 33/188] Installing readline-0:8.3-4.f 100% | 276.2 MiB/s | 565.6 KiB | 00m00s [ 34/188] Installing gmp-1:6.3.0-5.fc44 100% | 214.9 MiB/s | 660.1 KiB | 00m00s [ 35/188] Installing xz-libs-1:5.8.2-2. 100% | 260.2 MiB/s | 266.5 KiB | 00m00s [ 36/188] Installing libuuid-0:2.41.5-1 100% | 68.8 MiB/s | 70.4 KiB | 00m00s [ 37/188] Installing libzstd-0:1.5.7-5. 100% | 280.4 MiB/s | 861.5 KiB | 00m00s [ 38/188] Installing elfutils-libelf-0: 100% | 364.6 MiB/s | 1.5 MiB | 00m00s [ 39/188] Installing libacl-0:2.4.0-1.f 100% | 67.1 MiB/s | 68.8 KiB | 00m00s [ 40/188] Installing popt-0:1.19-10.fc4 100% | 49.2 MiB/s | 151.3 KiB | 00m00s [ 41/188] Installing systemd-libs-0:259 100% | 307.7 MiB/s | 2.5 MiB | 00m00s [ 42/188] Installing npth-0:1.8-4.fc44. 100% | 92.2 MiB/s | 94.4 KiB | 00m00s [ 43/188] Installing libblkid-0:2.41.5- 100% | 284.6 MiB/s | 291.5 KiB | 00m00s [ 44/188] Installing libxcrypt-0:4.5.2- 100% | 134.7 MiB/s | 275.9 KiB | 00m00s [ 45/188] Installing libsepol-0:3.11-1. 100% | 264.0 MiB/s | 810.9 KiB | 00m00s [ 46/188] Installing sqlite-libs-0:3.51 100% | 261.2 MiB/s | 1.6 MiB | 00m00s [ 47/188] Installing gnupg2-gpgconf-0:2 100% | 18.6 MiB/s | 323.9 KiB | 00m00s [ 48/188] Installing pcre2-0:10.47-1.fc 100% | 233.0 MiB/s | 715.7 KiB | 00m00s [ 49/188] Installing libselinux-0:3.11- 100% | 130.1 MiB/s | 266.4 KiB | 00m00s [ 50/188] Installing grep-0:3.12-3.fc44 100% | 49.4 MiB/s | 1.0 MiB | 00m00s [ 51/188] Installing sed-0:4.9-7.fc44.a 100% | 43.0 MiB/s | 881.3 KiB | 00m00s [ 52/188] Installing findutils-1:4.10.0 100% | 83.5 MiB/s | 1.9 MiB | 00m00s [ 53/188] Installing json-c-0:0.18-8.fc 100% | 136.5 MiB/s | 139.7 KiB | 00m00s [ 54/188] Installing libtasn1-0:4.21.0- 100% | 217.3 MiB/s | 222.5 KiB | 00m00s [ 55/188] Installing libunistring-0:1.1 100% | 291.0 MiB/s | 1.7 MiB | 00m00s [ 56/188] Installing libidn2-0:2.3.8-3. 100% | 61.5 MiB/s | 566.6 KiB | 00m00s [ 57/188] Installing crypto-policies-0: 100% | 25.7 MiB/s | 157.7 KiB | 00m00s [ 58/188] Installing xz-1:5.8.2-2.fc44. 100% | 60.3 MiB/s | 1.4 MiB | 00m00s [ 59/188] Installing libmount-0:2.41.5- 100% | 205.7 MiB/s | 421.3 KiB | 00m00s [ 60/188] Installing gnupg2-verify-0:2. 100% | 21.0 MiB/s | 365.7 KiB | 00m00s [ 61/188] Installing dwz-0:0.16-3.fc44. 100% | 19.8 MiB/s | 323.8 KiB | 00m00s [ 62/188] Installing mpfr-0:4.2.2-3.fc4 100% | 246.4 MiB/s | 757.1 KiB | 00m00s [ 63/188] Installing gawk-0:5.3.2-3.fc4 100% | 107.5 MiB/s | 2.6 MiB | 00m00s [ 64/188] Installing libksba-0:1.6.7-5. 100% | 195.7 MiB/s | 400.8 KiB | 00m00s [ 65/188] Installing unzip-0:6.0-69.fc4 100% | 30.9 MiB/s | 537.3 KiB | 00m00s [ 66/188] Installing file-libs-0:5.46-1 100% | 625.5 MiB/s | 11.9 MiB | 00m00s [ 67/188] Installing file-0:5.46-10.fc4 100% | 8.6 MiB/s | 141.6 KiB | 00m00s [ 68/188] Installing diffutils-0:3.12-5 100% | 77.3 MiB/s | 1.6 MiB | 00m00s [ 69/188] Installing libeconf-0:0.7.9-3 100% | 80.5 MiB/s | 82.5 KiB | 00m00s [ 70/188] Installing libsmartcols-0:2.4 100% | 220.2 MiB/s | 225.5 KiB | 00m00s [ 71/188] Installing lua-libs-0:5.4.8-5 100% | 161.7 MiB/s | 331.3 KiB | 00m00s [ 72/188] Installing libattr-0:2.6.0-1. 100% | 67.7 MiB/s | 69.3 KiB | 00m00s [ 73/188] Installing libcap-ng-0:0.9.6- 100% | 159.0 MiB/s | 162.8 KiB | 00m00s [ 74/188] Installing audit-libs-0:4.2.1 100% | 238.9 MiB/s | 489.3 KiB | 00m00s [ 75/188] Installing pam-libs-0:1.7.2-2 100% | 219.7 MiB/s | 225.0 KiB | 00m00s [ 76/188] Installing libcap-0:2.78-1.fc 100% | 29.5 MiB/s | 513.5 KiB | 00m00s [ 77/188] Installing libsemanage-0:3.11 100% | 176.7 MiB/s | 361.8 KiB | 00m00s [ 78/188] Installing alternatives-0:1.3 100% | 5.6 MiB/s | 91.6 KiB | 00m00s [ 79/188] Installing libffi-0:3.5.2-2.f 100% | 153.4 MiB/s | 157.1 KiB | 00m00s [ 80/188] Installing p11-kit-0:0.26.5-1 100% | 103.7 MiB/s | 2.8 MiB | 00m00s [ 81/188] Installing p11-kit-trust-0:0. 100% | 23.6 MiB/s | 531.9 KiB | 00m00s [ 82/188] Installing ngtcp2-0:1.22.1-1. 100% | 167.3 MiB/s | 342.7 KiB | 00m00s [ 83/188] Installing openssl-libs-1:3.5 100% | 340.2 MiB/s | 7.5 MiB | 00m00s [ 84/188] Installing coreutils-0:9.10-5 100% | 191.2 MiB/s | 8.2 MiB | 00m00s [ 85/188] Installing ca-certificates-0: 100% | 1.6 MiB/s | 2.5 MiB | 00m02s [ 86/188] Installing gzip-0:1.14-2.fc44 100% | 22.8 MiB/s | 443.0 KiB | 00m00s [ 87/188] Installing libfsverity-0:1.6- 100% | 67.7 MiB/s | 69.3 KiB | 00m00s [ 88/188] Installing rpm-sequoia-0:1.10 100% | 327.4 MiB/s | 2.3 MiB | 00m00s [ 89/188] Installing libevent-0:2.1.13- 100% | 271.7 MiB/s | 1.1 MiB | 00m00s [ 90/188] Installing ngtcp2-crypto-ossl 100% | 66.7 MiB/s | 68.3 KiB | 00m00s [ 91/188] Installing liblastlog2-0:2.41 100% | 27.3 MiB/s | 139.8 KiB | 00m00s [ 92/188] Installing util-linux-core-0: 100% | 94.8 MiB/s | 2.5 MiB | 00m00s [ 93/188] Installing zip-0:3.0-45.fc44. 100% | 41.5 MiB/s | 765.8 KiB | 00m00s [ 94/188] Installing gnupg2-keyboxd-0:2 100% | 38.2 MiB/s | 234.5 KiB | 00m00s [ 95/188] Installing libpsl-0:0.21.5-7. 100% | 130.3 MiB/s | 133.4 KiB | 00m00s [ 96/188] Installing tar-2:1.35-9.fc44. 100% | 115.6 MiB/s | 3.0 MiB | 00m00s [ 97/188] Installing linkdupes-0:0.7.3- 100% | 38.8 MiB/s | 715.1 KiB | 00m00s [ 98/188] Installing libselinux-utils-0 100% | 67.8 MiB/s | 1.4 MiB | 00m00s [ 99/188] Installing systemd-standalone 100% | 19.0 MiB/s | 330.2 KiB | 00m00s [100/188] Installing rpm-libs-0:6.0.2-1 100% | 243.3 MiB/s | 996.7 KiB | 00m00s [101/188] Installing libfdisk-0:2.41.5- 100% | 136.7 MiB/s | 419.9 KiB | 00m00s [102/188] Installing util-linux-0:2.41. 100% | 145.9 MiB/s | 6.9 MiB | 00m00s [103/188] Installing policycoreutils-0: 100% | 49.3 MiB/s | 1.5 MiB | 00m00s [104/188] Installing selinux-policy-0:4 100% | 1.7 MiB/s | 34.5 KiB | 00m00s [105/188] Installing selinux-policy-tar 100% | 147.6 MiB/s | 14.9 MiB | 00m00s [106/188] Installing libusb1-0:1.0.30-1 100% | 22.1 MiB/s | 181.4 KiB | 00m00s >>> Running sysusers scriptlet: tpm2-tss-0:4.1.3-9.fc44.aarch64 >>> Finished sysusers scriptlet: tpm2-tss-0:4.1.3-9.fc44.aarch64 >>> Scriptlet output: >>> Creating group 'tss' with GID 59. >>> Creating user 'tss' (Account used for TPM access) with UID 59 and GID 59. >>> [107/188] Installing tpm2-tss-0:4.1.3-9 100% | 269.6 MiB/s | 2.2 MiB | 00m00s [108/188] Installing ima-evm-utils-libs 100% | 91.7 MiB/s | 93.9 KiB | 00m00s [109/188] Installing gnupg2-gpg-agent-0 100% | 34.6 MiB/s | 850.9 KiB | 00m00s [110/188] Installing zstd-0:1.5.7-5.fc4 100% | 29.1 MiB/s | 565.8 KiB | 00m00s [111/188] Installing libxml2-0:2.12.10- 100% | 86.0 MiB/s | 1.9 MiB | 00m00s [112/188] Installing nettle-0:3.10.1-3. 100% | 250.1 MiB/s | 768.2 KiB | 00m00s [113/188] Installing gnutls-0:3.8.13-1. 100% | 337.2 MiB/s | 3.7 MiB | 00m00s [114/188] Installing bzip2-0:1.0.8-23.f 100% | 10.1 MiB/s | 175.6 KiB | 00m00s [115/188] Installing add-determinism-0: 100% | 89.6 MiB/s | 2.0 MiB | 00m00s [116/188] Installing build-reproducibil 100% | 0.0 B/s | 1.5 KiB | 00m00s [117/188] Installing cpio-0:2.15-9.fc44 100% | 54.8 MiB/s | 1.1 MiB | 00m00s [118/188] Installing ed-0:1.22.5-2.fc44 100% | 9.2 MiB/s | 160.1 KiB | 00m00s [119/188] Installing patch-0:2.8-4.fc44 100% | 15.2 MiB/s | 263.9 KiB | 00m00s [120/188] Installing libpkgconf-0:2.5.1 100% | 132.0 MiB/s | 135.2 KiB | 00m00s [121/188] Installing pkgconf-0:2.5.1-1. 100% | 7.3 MiB/s | 119.3 KiB | 00m00s [122/188] Installing pkgconf-pkg-config 100% | 110.8 KiB/s | 1.8 KiB | 00m00s [123/188] Installing libgomp-0:16.2.1-2 100% | 290.2 MiB/s | 594.3 KiB | 00m00s [124/188] Installing jansson-0:2.14-4.f 100% | 92.2 MiB/s | 94.4 KiB | 00m00s [125/188] Installing lz4-libs-0:1.10.0- 100% | 193.7 MiB/s | 198.4 KiB | 00m00s [126/188] Installing libarchive-0:3.8.7 100% | 238.7 MiB/s | 977.5 KiB | 00m00s [127/188] Installing libtool-ltdl-0:2.5 100% | 92.8 MiB/s | 95.0 KiB | 00m00s [128/188] Installing gdbm-libs-1:1.23-1 100% | 229.9 MiB/s | 235.4 KiB | 00m00s [129/188] Installing cyrus-sasl-lib-0:2 100% | 105.1 MiB/s | 2.4 MiB | 00m00s [130/188] Installing openldap-0:2.6.15- 100% | 187.8 MiB/s | 769.4 KiB | 00m00s [131/188] Installing gnupg2-dirmngr-0:2 100% | 27.5 MiB/s | 648.9 KiB | 00m00s [132/188] Installing gnupg2-0:2.4.9-16. 100% | 179.4 MiB/s | 6.5 MiB | 00m00s [133/188] Installing rpm-sign-libs-0:6. 100% | 66.9 MiB/s | 68.5 KiB | 00m00s [134/188] Installing gpgverify-0:2.2-4. 100% | 0.0 B/s | 9.4 KiB | 00m00s [135/188] Installing libpfm-0:4.13.0-20 100% | 247.4 MiB/s | 253.3 KiB | 00m00s [136/188] Installing xxhash-libs-0:0.8. 100% | 85.1 MiB/s | 87.2 KiB | 00m00s [137/188] Installing libnghttp3-0:1.18. 100% | 203.3 MiB/s | 208.2 KiB | 00m00s [138/188] Installing libbrotli-0:1.2.0- 100% | 222.5 MiB/s | 911.3 KiB | 00m00s [139/188] Installing libcbor-0:0.13.0-2 100% | 137.6 MiB/s | 140.9 KiB | 00m00s [140/188] Installing libfido2-0:1.16.0- 100% | 136.8 MiB/s | 280.1 KiB | 00m00s [141/188] Installing keyutils-libs-0:1. 100% | 97.3 MiB/s | 99.6 KiB | 00m00s [142/188] Installing libcom_err-0:1.47. 100% | 109.5 MiB/s | 112.1 KiB | 00m00s [143/188] Installing libverto-0:0.3.2-1 100% | 69.4 MiB/s | 71.1 KiB | 00m00s [144/188] Installing krb5-libs-0:1.22.2 100% | 281.5 MiB/s | 2.5 MiB | 00m00s [145/188] Installing libssh-0:0.12.2-1. 100% | 235.5 MiB/s | 723.4 KiB | 00m00s [146/188] Installing libnghttp2-0:1.68. 100% | 194.4 MiB/s | 199.1 KiB | 00m00s [147/188] Installing libcurl-0:8.18.0-1 100% | 239.8 MiB/s | 982.0 KiB | 00m00s [148/188] Installing curl-0:8.18.0-14.f 100% | 17.5 MiB/s | 466.8 KiB | 00m00s [149/188] Installing rpm-0:6.0.2-1.fc44 100% | 69.8 MiB/s | 2.8 MiB | 00m00s [150/188] Installing cmake-srpm-macros- 100% | 0.0 B/s | 804.0 B | 00m00s [151/188] Installing efi-srpm-macros-0: 100% | 40.2 MiB/s | 41.2 KiB | 00m00s [152/188] Installing java-srpm-macros-0 100% | 0.0 B/s | 1.1 KiB | 00m00s [153/188] Installing lua-srpm-macros-0: 100% | 0.0 B/s | 1.9 KiB | 00m00s [154/188] Installing tree-sitter-srpm-m 100% | 9.1 MiB/s | 9.3 KiB | 00m00s [155/188] Installing zig-srpm-macros-0: 100% | 0.0 B/s | 1.9 KiB | 00m00s [156/188] Installing filesystem-srpm-ma 100% | 38.0 MiB/s | 38.9 KiB | 00m00s [157/188] Installing elfutils-default-y 100% | 408.6 KiB/s | 2.0 KiB | 00m00s [158/188] Installing elfutils-libs-0:0. 100% | 182.7 MiB/s | 748.5 KiB | 00m00s [159/188] Installing elfutils-debuginfo 100% | 8.4 MiB/s | 146.1 KiB | 00m00s [160/188] Installing elfutils-0:0.196-1 100% | 140.0 MiB/s | 3.8 MiB | 00m00s [161/188] Installing binutils-0:2.46.1- 100% | 311.8 MiB/s | 31.5 MiB | 00m00s [162/188] Installing gdb-minimal-0:17.2 100% | 250.6 MiB/s | 13.5 MiB | 00m00s [163/188] Installing debugedit-0:5.3-2. 100% | 17.6 MiB/s | 324.2 KiB | 00m00s [164/188] Installing rpm-build-libs-0:6 100% | 129.4 MiB/s | 264.9 KiB | 00m00s [165/188] Installing qt5-srpm-macros-0: 100% | 0.0 B/s | 776.0 B | 00m00s [166/188] Installing perl-srpm-macros-0 100% | 0.0 B/s | 1.1 KiB | 00m00s [167/188] Installing openblas-srpm-macr 100% | 0.0 B/s | 392.0 B | 00m00s [168/188] Installing ocaml-srpm-macros- 100% | 0.0 B/s | 2.1 KiB | 00m00s [169/188] Installing kernel-srpm-macros 100% | 0.0 B/s | 2.3 KiB | 00m00s [170/188] Installing gnat-srpm-macros-0 100% | 0.0 B/s | 1.3 KiB | 00m00s [171/188] Installing ghc-srpm-macros-0: 100% | 0.0 B/s | 1.0 KiB | 00m00s [172/188] Installing gap-srpm-macros-0: 100% | 0.0 B/s | 2.7 KiB | 00m00s [173/188] Installing fpc-srpm-macros-0: 100% | 0.0 B/s | 420.0 B | 00m00s [174/188] Installing ansible-srpm-macro 100% | 0.0 B/s | 36.2 KiB | 00m00s [175/188] Installing gnome-srpm-macros- 100% | 4.0 MiB/s | 4.1 KiB | 00m00s [176/188] Installing rpm-build-0:6.0.2- 100% | 31.2 MiB/s | 607.8 KiB | 00m00s [177/188] Installing erlang-srpm-macros 100% | 2.5 MiB/s | 2.6 KiB | 00m00s [178/188] Installing pyproject-srpm-mac 100% | 3.9 MiB/s | 4.0 KiB | 00m00s [179/188] Installing redhat-rpm-config- 100% | 26.5 MiB/s | 189.9 KiB | 00m00s [180/188] Installing forge-srpm-macros- 100% | 39.3 MiB/s | 40.3 KiB | 00m00s [181/188] Installing fonts-srpm-macros- 100% | 55.7 MiB/s | 57.0 KiB | 00m00s [182/188] Installing go-srpm-macros-0:3 100% | 61.6 MiB/s | 63.0 KiB | 00m00s [183/188] Installing python-srpm-macros 100% | 51.7 MiB/s | 52.9 KiB | 00m00s [184/188] Installing R-srpm-macros-0:1. 100% | 0.0 B/s | 4.4 KiB | 00m00s [185/188] Installing rpm-plugin-selinux 100% | 67.3 MiB/s | 68.9 KiB | 00m00s [186/188] Installing which-0:2.25-1.fc4 100% | 6.8 MiB/s | 125.8 KiB | 00m00s [187/188] Installing shadow-utils-2:4.1 100% | 115.2 MiB/s | 4.5 MiB | 00m00s [188/188] Installing info-0:7.2-9.fc44. 100% | 52.5 KiB/s | 421.9 KiB | 00m08s Complete! Finish: installing minimal buildroot with dnf5 Start: creating root cache Finish: creating root cache Finish: chroot init INFO: Installed packages: INFO: R-srpm-macros-1.3.7-2.fc44.noarch add-determinism-0.7.3-2.fc44.aarch64 alternatives-1.33-5.fc44.aarch64 ansible-srpm-macros-1-20.1.fc44.noarch audit-libs-4.2.1-1.fc44.aarch64 bash-5.3.9-3.fc44.aarch64 binutils-2.46.1-1.fc44.aarch64 build-reproducibility-srpm-macros-0.7.3-2.fc44.noarch bzip2-1.0.8-23.fc44.aarch64 bzip2-libs-1.0.8-23.fc44.aarch64 ca-certificates-2026.2.92_v9.0.319-2.fc44.noarch cmake-srpm-macros-4.3.0-1.fc44.noarch coreutils-9.10-5.fc44.aarch64 coreutils-common-9.10-5.fc44.aarch64 cpio-2.15-9.fc44.aarch64 crypto-policies-20251128-3.git19878fe.fc44.noarch curl-8.18.0-14.fc44.aarch64 cyrus-sasl-lib-2.1.28-35.fc44.aarch64 debugedit-5.3-2.fc44.aarch64 diffutils-3.12-5.fc44.aarch64 dwz-0.16-3.fc44.aarch64 ed-1.22.5-2.fc44.aarch64 efi-srpm-macros-6-6.fc44.noarch elfutils-0.196-1.fc44.aarch64 elfutils-debuginfod-client-0.196-1.fc44.aarch64 elfutils-default-yama-scope-0.196-1.fc44.noarch elfutils-libelf-0.196-1.fc44.aarch64 elfutils-libs-0.196-1.fc44.aarch64 erlang-srpm-macros-0.4.0-1.fc44.noarch fedora-gpg-keys-44-2.noarch fedora-release-44-18.noarch fedora-release-common-44-18.noarch fedora-release-identity-basic-44-18.noarch fedora-repos-44-2.noarch file-5.46-10.fc44.aarch64 file-libs-5.46-10.fc44.aarch64 filesystem-3.18-52.fc44.aarch64 filesystem-srpm-macros-3.18-52.fc44.noarch findutils-4.10.0-7.fc44.aarch64 fonts-srpm-macros-5.0.0-2.fc44.noarch forge-srpm-macros-0.4.0-4.fc44.noarch fpc-srpm-macros-1.3-16.fc44.noarch gap-srpm-macros-2-2.fc44.noarch gawk-5.3.2-3.fc44.aarch64 gdb-minimal-17.2-4.fc44.aarch64 gdbm-libs-1.23-11.fc44.aarch64 ghc-srpm-macros-1.10-1.fc44.noarch glibc-2.43-9.fc44.aarch64 glibc-common-2.43-9.fc44.aarch64 glibc-gconv-extra-2.43-9.fc44.aarch64 glibc-minimal-langpack-2.43-9.fc44.aarch64 gmp-6.3.0-5.fc44.aarch64 gnat-srpm-macros-7-2.fc44.noarch gnome-srpm-macros-1.0-1.fc44.noarch gnulib-l10n-20241231-2.fc44.noarch gnupg2-2.4.9-16.fc44.aarch64 gnupg2-dirmngr-2.4.9-16.fc44.aarch64 gnupg2-gpg-agent-2.4.9-16.fc44.aarch64 gnupg2-gpgconf-2.4.9-16.fc44.aarch64 gnupg2-keyboxd-2.4.9-16.fc44.aarch64 gnupg2-verify-2.4.9-16.fc44.aarch64 gnutls-3.8.13-1.fc44.aarch64 go-srpm-macros-3.8.0-2.fc44.noarch gpg-pubkey-36f612dcf27f7d1a48a835e4dbfcf71c6d9f90a6-6786af3b gpgverify-2.2-4.fc44.noarch grep-3.12-3.fc44.aarch64 gzip-1.14-2.fc44.aarch64 ima-evm-utils-libs-1.6.2-8.fc44.aarch64 info-7.2-9.fc44.aarch64 jansson-2.14-4.fc44.aarch64 java-srpm-macros-1-8.fc44.noarch json-c-0.18-8.fc44.aarch64 kernel-srpm-macros-1.0-28.fc44.noarch keyutils-libs-1.6.3-7.fc44.aarch64 krb5-libs-1.22.2-4.fc44.aarch64 libacl-2.4.0-1.fc44.aarch64 libarchive-3.8.7-1.fc44.aarch64 libassuan-2.5.7-5.fc44.aarch64 libattr-2.6.0-1.fc44.aarch64 libblkid-2.41.5-1.fc44.aarch64 libbrotli-1.2.0-3.fc44.aarch64 libcap-2.78-1.fc44.aarch64 libcap-ng-0.9.6-1.fc44.aarch64 libcbor-0.13.0-2.fc44.aarch64 libcom_err-1.47.3-4.fc44.aarch64 libcurl-8.18.0-14.fc44.aarch64 libeconf-0.7.9-3.fc44.aarch64 libevent-2.1.13-1.fc44.aarch64 libfdisk-2.41.5-1.fc44.aarch64 libffi-3.5.2-2.fc44.aarch64 libfido2-1.16.0-5.fc44.aarch64 libfsverity-1.6-4.fc44.aarch64 libgcc-16.2.1-2.fc44.aarch64 libgcrypt-1.12.2-1.fc44.aarch64 libgomp-16.2.1-2.fc44.aarch64 libgpg-error-1.58-2.fc44.aarch64 libidn2-2.3.8-3.fc44.aarch64 libksba-1.6.7-5.fc44.aarch64 liblastlog2-2.41.5-1.fc44.aarch64 libmount-2.41.5-1.fc44.aarch64 libnghttp2-1.68.0-5.fc44.aarch64 libnghttp3-1.18.0-1.fc44.aarch64 libpfm-4.13.0-20.fc44.aarch64 libpkgconf-2.5.1-1.fc44.aarch64 libpsl-0.21.5-7.fc44.aarch64 libselinux-3.11-2.fc44.aarch64 libselinux-utils-3.11-2.fc44.aarch64 libsemanage-3.11-1.fc44.aarch64 libsepol-3.11-1.fc44.aarch64 libsmartcols-2.41.5-1.fc44.aarch64 libssh-0.12.2-1.fc44.aarch64 libssh-config-0.12.2-1.fc44.noarch libstdc++-16.2.1-2.fc44.aarch64 libtasn1-4.21.0-1.fc44.aarch64 libtool-ltdl-2.5.4-10.fc44.aarch64 libunistring-1.1-11.fc44.aarch64 libusb1-1.0.30-1.fc44.aarch64 libuuid-2.41.5-1.fc44.aarch64 libverto-0.3.2-12.fc44.aarch64 libxcrypt-4.5.2-3.fc44.aarch64 libxml2-2.12.10-6.fc44.aarch64 libzstd-1.5.7-5.fc44.aarch64 linkdupes-0.7.3-2.fc44.aarch64 lua-libs-5.4.8-5.fc44.aarch64 lua-srpm-macros-1-17.fc44.noarch lz4-libs-1.10.0-4.fc44.aarch64 mpfr-4.2.2-3.fc44.aarch64 ncurses-base-6.6-1.fc44.noarch ncurses-libs-6.6-1.fc44.aarch64 nettle-3.10.1-3.fc44.aarch64 ngtcp2-1.22.1-1.fc44.aarch64 ngtcp2-crypto-ossl-1.22.1-1.fc44.aarch64 npth-1.8-4.fc44.aarch64 ocaml-srpm-macros-11-3.fc44.noarch openblas-srpm-macros-2-21.fc44.noarch openldap-2.6.15-1.fc44.aarch64 openssl-libs-3.5.9-1.fc44.aarch64 p11-kit-0.26.5-1.fc44.aarch64 p11-kit-trust-0.26.5-1.fc44.aarch64 package-notes-srpm-macros-0.20-1.fc44.noarch pam-libs-1.7.2-2.fc44.aarch64 patch-2.8-4.fc44.aarch64 pcre2-10.47-1.fc44.1.aarch64 pcre2-syntax-10.47-1.fc44.1.noarch perl-srpm-macros-1-61.fc44.noarch pkgconf-2.5.1-1.fc44.aarch64 pkgconf-m4-2.5.1-1.fc44.noarch pkgconf-pkg-config-2.5.1-1.fc44.aarch64 policycoreutils-3.11-2.fc44.aarch64 popt-1.19-10.fc44.aarch64 publicsuffix-list-dafsa-20260116-1.fc44.noarch pyproject-srpm-macros-1.24.0-1.fc44.noarch python-srpm-macros-3.14-12.fc44.noarch qt5-srpm-macros-5.15.18-2.fc44.noarch qt6-srpm-macros-6.11.2-1.fc44.noarch readline-8.3-4.fc44.aarch64 redhat-rpm-config-344-2.fc44.noarch rpm-6.0.2-1.fc44.aarch64 rpm-build-6.0.2-1.fc44.aarch64 rpm-build-libs-6.0.2-1.fc44.aarch64 rpm-libs-6.0.2-1.fc44.aarch64 rpm-plugin-selinux-6.0.2-1.fc44.aarch64 rpm-sequoia-1.10.3-1.fc44.aarch64 rpm-sign-libs-6.0.2-1.fc44.aarch64 rust-srpm-macros-28.5-1.fc44.noarch sed-4.9-7.fc44.aarch64 selinux-policy-44.11-1.fc44.noarch selinux-policy-targeted-44.11-1.fc44.noarch setup-2.15.0-28.fc44.noarch shadow-utils-4.19.0-7.fc44.aarch64 sqlite-libs-3.51.2-2.fc44.aarch64 systemd-libs-259.10-1.fc44.aarch64 systemd-standalone-sysusers-259.10-1.fc44.aarch64 tar-1.35-9.fc44.aarch64 tpm2-tss-4.1.3-9.fc44.aarch64 tree-sitter-srpm-macros-0.4.2-2.fc44.noarch unzip-6.0-69.fc44.aarch64 util-linux-2.41.5-1.fc44.aarch64 util-linux-core-2.41.5-1.fc44.aarch64 which-2.25-1.fc44.aarch64 xxhash-libs-0.8.4-1.fc44.aarch64 xz-5.8.2-2.fc44.aarch64 xz-libs-5.8.2-2.fc44.aarch64 zig-srpm-macros-1-8.fc44.noarch zip-3.0-45.fc44.aarch64 zlib-ng-compat-2.3.3-3.fc44.aarch64 zstd-1.5.7-5.fc44.aarch64 Start: buildsrpm Start: rpmbuild -bs Building target platforms: aarch64 Building for target aarch64 setting SOURCE_DATE_EPOCH=1792713600 Wrote: /builddir/build/SRPMS/python-sbmlutils-0.17.0-1.fc44.src.rpm Finish: rpmbuild -bs INFO: chroot_scan: 1 files copied to /var/lib/copr-rpmbuild/results/chroot_scan INFO: /var/lib/mock/fedora-44-aarch64-1792824741.766395/root/var/log/dnf5.log INFO: chroot_scan: creating tarball /var/lib/copr-rpmbuild/results/chroot_scan.tar.gz /bin/tar: Removing leading `/' from member names Finish: buildsrpm INFO: Done(/var/lib/copr-rpmbuild/workspace/workdir-tgbdc6k5/python-sbmlutils/python-sbmlutils.spec) Config(child) 0 minutes 18 seconds INFO: Results and/or logs in: /var/lib/copr-rpmbuild/results INFO: Cleaning up build root ('cleanup_on_success=True') Start: clean chroot INFO: unmounting tmpfs. Finish: clean chroot INFO: Start(/var/lib/copr-rpmbuild/results/python-sbmlutils-0.17.0-1.fc44.src.rpm) Config(fedora-44-aarch64) Start(bootstrap): chroot init INFO: mounting tmpfs at /var/lib/mock/fedora-44-aarch64-bootstrap-1792824741.766395/root. INFO: reusing tmpfs at /var/lib/mock/fedora-44-aarch64-bootstrap-1792824741.766395/root. INFO: calling preinit hooks INFO: enabled root cache INFO: enabled package manager cache Start(bootstrap): cleaning package manager metadata Finish(bootstrap): cleaning package manager metadata Finish(bootstrap): chroot init Start: chroot init INFO: mounting tmpfs at /var/lib/mock/fedora-44-aarch64-1792824741.766395/root. INFO: calling preinit hooks INFO: enabled root cache Start: unpacking root cache Finish: unpacking root cache INFO: enabled package manager cache Start: cleaning package manager metadata Finish: cleaning package manager metadata INFO: enabled HW Info plugin INFO: Buildroot is handled by package management downloaded with a bootstrap image: rpm-6.0.2-1.fc44.aarch64 rpm-sequoia-1.10.3-1.fc44.aarch64 dnf5-5.4.6.0-1.fc44.aarch64 dnf5-plugins-5.4.6.0-1.fc44.aarch64 Finish: chroot init Start: build phase for python-sbmlutils-0.17.0-1.fc44.src.rpm Start: build setup for python-sbmlutils-0.17.0-1.fc44.src.rpm Building target platforms: aarch64 Building for target aarch64 setting SOURCE_DATE_EPOCH=1792713600 Wrote: /builddir/build/SRPMS/python-sbmlutils-0.17.0-1.fc44.src.rpm Updating and loading repositories: updates 100% | 57.6 KiB/s | 9.8 KiB | 00m00s fedora 100% | 59.7 KiB/s | 10.2 KiB | 00m00s Additional repo copr_mhough_neurofedor 100% | 15.1 KiB/s | 1.5 KiB | 00m00s Copr repository 100% | 15.0 KiB/s | 1.5 KiB | 00m00s Repositories loaded. Package Arch Version Repository Size Installing: pyproject-rpm-macros noarch 0:1.24.0-1.fc44 updates 169.0 KiB python3-devel aarch64 0:3.14.8-1.fc44 updates 2.0 MiB python3-libsbml aarch64 0:5.20.5-100.fc44.biofedora copr_base 33.7 MiB python3-matplotlib aarch64 0:3.10.8-2.fc44 fedora 31.8 MiB python3-pytest noarch 0:8.4.2-2.fc44 fedora 22.5 MiB python3-roadrunner aarch64 0:2.10.0-11.fc44 copr_base 11.0 MiB Installing dependencies: abattis-cantarell-vf-fonts noarch 0:0.301-17.fc44 fedora 192.7 KiB blas aarch64 0:3.12.0-11.fc44 fedora 1.2 MiB cairo aarch64 0:1.18.6-1.fc44 updates 1.8 MiB default-fonts-core-sans noarch 0:4.3-1.fc44 fedora 11.9 KiB dejavu-sans-fonts noarch 0:2.37-29.fc44 fedora 5.5 MiB expat aarch64 0:2.8.5-1.fc44 updates 386.2 KiB flexiblas aarch64 0:3.5.0-2.fc44 fedora 38.0 KiB flexiblas-netlib aarch64 0:3.5.0-2.fc44 fedora 14.2 MiB flexiblas-openblas-openmp aarch64 0:3.5.0-2.fc44 fedora 67.2 KiB fontconfig aarch64 0:2.17.0-4.fc44 fedora 1.2 MiB fonts-filesystem noarch 1:5.0.0-2.fc44 fedora 0.0 B freetype aarch64 0:2.14.3-1.fc44 updates 878.6 KiB fribidi aarch64 0:1.0.16-4.fc44 fedora 246.0 KiB glib2 aarch64 0:2.88.4-1.fc44 updates 15.9 MiB google-noto-fonts-common noarch 0:20251201-2.fc44 fedora 17.7 KiB google-noto-sans-vf-fonts noarch 0:20251201-2.fc44 fedora 1.4 MiB graphite2 aarch64 0:1.3.14-20.fc44 fedora 239.3 KiB harfbuzz aarch64 0:14.1.0-2.fc44 updates 2.7 MiB jbigkit-libs aarch64 0:2.1-33.fc44 fedora 181.2 KiB lapack aarch64 0:3.12.0-11.fc44 fedora 14.9 MiB lcms2 aarch64 0:2.16-7.fc44 fedora 484.7 KiB libX11 aarch64 0:1.8.13-3.fc44 updates 1.3 MiB libX11-common noarch 0:1.8.13-3.fc44 updates 1.1 MiB libXau aarch64 0:1.0.12-4.fc44 fedora 120.8 KiB libXext aarch64 0:1.3.6-5.fc44 fedora 145.7 KiB libXrender aarch64 0:0.9.12-4.fc44 fedora 69.9 KiB libedit aarch64 0:3.1-59.20260512cvs.fc44 updates 280.3 KiB libgfortran aarch64 0:16.2.1-2.fc44 updates 1.7 MiB libimagequant aarch64 0:4.1.0-2.fc44 fedora 672.1 KiB libjpeg-turbo aarch64 0:3.1.3-1.fc44 fedora 677.7 KiB liblerc aarch64 0:4.0.0-10.fc44 fedora 546.3 KiB libpng aarch64 2:1.6.58-1.fc44 updates 269.7 KiB libqhull_r aarch64 1:8.0.2-8.fc44 fedora 455.3 KiB libraqm aarch64 0:0.10.1-4.fc44 fedora 68.5 KiB libsbml aarch64 0:5.20.5-100.fc44.biofedora copr_base 9.9 MiB libtiff aarch64 0:4.7.2-3.fc44 updates 659.4 KiB libwebp aarch64 0:1.6.0-3.fc44 fedora 816.8 KiB libxcb aarch64 0:1.17.0-7.fc44 fedora 2.1 MiB llvm13-libs aarch64 0:13.0.1-8.fc41 fedora 81.3 MiB lzo aarch64 0:2.10-16.fc44 fedora 162.8 KiB minizip-ng-compat aarch64 0:4.1.0-1.fc44 fedora 198.4 KiB mpdecimal aarch64 0:4.0.1-3.fc44 fedora 281.1 KiB openblas aarch64 0:0.3.29-2.fc43 fedora 111.7 KiB openblas-openmp aarch64 0:0.3.29-2.fc43 fedora 20.4 MiB openjpeg aarch64 0:2.5.4-3.fc44 fedora 412.2 KiB pixman aarch64 0:0.46.2-3.fc44 fedora 654.3 KiB poco-foundation aarch64 0:1.14.1-3.fc44 fedora 2.2 MiB poco-net aarch64 0:1.14.1-3.fc44 fedora 1.4 MiB python-pip-wheel noarch 0:26.0.1-3.fc44 updates 1.2 MiB python-rpm-macros noarch 0:3.14-12.fc44 fedora 28.0 KiB python3 aarch64 0:3.14.8-1.fc44 updates 84.7 KiB python3-cairo aarch64 0:1.28.0-5.fc44 fedora 516.6 KiB python3-contourpy aarch64 0:1.4.0-1.fc44 updates 860.5 KiB python3-cycler noarch 0:0.11.0-20.fc44 fedora 37.8 KiB python3-dateutil noarch 1:2.9.0.post0-7.fc44 fedora 878.0 KiB python3-fonttools aarch64 0:4.62.1-1.fc44 updates 19.4 MiB python3-iniconfig noarch 0:2.3.0-2.fc44 fedora 49.8 KiB python3-kiwisolver aarch64 0:1.5.1-1.fc44 updates 161.1 KiB python3-libs aarch64 0:3.14.8-1.fc44 updates 45.7 MiB python3-matplotlib-data-fonts aarch64 0:3.10.8-2.fc44 fedora 7.9 MiB python3-numpy aarch64 1:2.4.6-1.fc44 updates 36.3 MiB python3-numpy-f2py aarch64 1:2.4.6-1.fc44 updates 2.1 MiB python3-olefile noarch 0:0.47-13.fc44 fedora 346.5 KiB python3-packaging noarch 0:25.0-8.fc44 fedora 607.4 KiB python3-pillow aarch64 0:12.3.0-1.fc44 updates 4.6 MiB python3-pluggy noarch 0:1.6.0-5.fc44 fedora 211.5 KiB python3-pygments noarch 0:2.19.1-9.fc44 fedora 11.3 MiB python3-pyparsing noarch 0:3.1.2-15.fc44 fedora 1.0 MiB python3-rpm-generators noarch 0:14-14.fc44 fedora 81.7 KiB python3-rpm-macros noarch 0:3.14-12.fc44 fedora 6.5 KiB python3-six noarch 0:1.17.0-8.fc44 fedora 118.0 KiB rr-libstruct aarch64 0:2.9.2-0.4.git7ff1f47.fc44 copr_base 261.1 KiB tzdata noarch 0:2026e-1.fc44 updates 1.3 MiB utf8proc aarch64 0:2.11.3-2.fc44 fedora 413.5 KiB xml-common noarch 0:0.6.3-68.fc44 fedora 78.4 KiB Transaction Summary: Installing: 81 packages Total size of inbound packages is 102 MiB. Need to download 26 MiB. After this operation, 426 MiB extra will be used (install 426 MiB, remove 0 B). [ 1/81] python3-pytest-0:8.4.2-2.fc44.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 2/81] python3-roadrunner-0:2.10.0-11. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 3/81] pyproject-rpm-macros-0:1.24.0-1 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 4/81] python3-devel-0:3.14.8-1.fc44.a 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 5/81] python3-libsbml-0:5.20.5-100.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 6/81] python3-dateutil-1:2.9.0.post0- 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 7/81] python3-packaging-0:25.0-8.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 8/81] python3-iniconfig-0:2.3.0-2.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 9/81] python3-pluggy-0:1.6.0-5.fc44.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [10/81] python3-pygments-0:2.19.1-9.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [11/81] llvm13-libs-0:13.0.1-8.fc41.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [12/81] poco-foundation-0:1.14.1-3.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [13/81] poco-net-0:1.14.1-3.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [14/81] rr-libstruct-0:2.9.2-0.4.git7ff 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [15/81] python-rpm-macros-0:3.14-12.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [16/81] python3-rpm-macros-0:3.14-12.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [17/81] python3-0:3.14.8-1.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [18/81] python3-libs-0:3.14.8-1.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [19/81] minizip-ng-compat-0:4.1.0-1.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [20/81] libsbml-0:5.20.5-100.fc44.biofe 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [21/81] python3-six-0:1.17.0-8.fc44.noa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [22/81] utf8proc-0:2.11.3-2.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [23/81] lapack-0:3.12.0-11.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [24/81] expat-0:2.8.5-1.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [25/81] mpdecimal-0:4.0.1-3.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [26/81] blas-0:3.12.0-11.fc44.aarch64 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [27/81] python3-numpy-1:2.4.6-1.fc44.aa 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [28/81] python3-numpy-f2py-1:2.4.6-1.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [29/81] flexiblas-netlib-0:3.5.0-2.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [30/81] flexiblas-0:3.5.0-2.fc44.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [31/81] flexiblas-openblas-openmp-0:3.5 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [32/81] openblas-openmp-0:0.3.29-2.fc43 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [33/81] openblas-0:0.3.29-2.fc43.aarch6 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [34/81] tzdata-0:2026e-1.fc44.noarch 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [35/81] libgfortran-0:16.2.1-2.fc44.aar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [36/81] libedit-0:3.1-59.20260512cvs.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [37/81] python-pip-wheel-0:26.0.1-3.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [38/81] python3-rpm-generators-0:14-14. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [39/81] libqhull_r-1:8.0.2-8.fc44.aarch 100% | 10.6 MiB/s | 194.7 KiB | 00m00s [40/81] python3-cairo-0:1.28.0-5.fc44.a 100% | 17.9 MiB/s | 128.2 KiB | 00m00s [41/81] python3-cycler-0:0.11.0-20.fc44 100% | 1.9 MiB/s | 22.0 KiB | 00m00s [42/81] python3-matplotlib-0:3.10.8-2.f 100% | 154.0 MiB/s | 7.9 MiB | 00m00s [43/81] dejavu-sans-fonts-0:2.37-29.fc4 100% | 24.1 MiB/s | 1.3 MiB | 00m00s [44/81] python3-matplotlib-data-fonts-0 100% | 101.8 MiB/s | 2.3 MiB | 00m00s [45/81] python3-pyparsing-0:3.1.2-15.fc 100% | 28.0 MiB/s | 286.8 KiB | 00m00s [46/81] fonts-filesystem-1:5.0.0-2.fc44 100% | 1.2 MiB/s | 8.9 KiB | 00m00s [47/81] freetype-0:2.14.3-1.fc44.aarch6 100% | 203.0 MiB/s | 415.7 KiB | 00m00s [48/81] python3-contourpy-0:1.4.0-1.fc4 100% | 69.3 MiB/s | 283.7 KiB | 00m00s [49/81] python3-kiwisolver-0:1.5.1-1.fc 100% | 12.6 MiB/s | 64.5 KiB | 00m00s [50/81] python3-pillow-0:12.3.0-1.fc44. 100% | 114.2 MiB/s | 1.0 MiB | 00m00s [51/81] lcms2-0:2.16-7.fc44.aarch64 100% | 22.1 MiB/s | 181.0 KiB | 00m00s [52/81] python3-fonttools-0:4.62.1-1.fc 100% | 162.2 MiB/s | 3.2 MiB | 00m00s [53/81] libimagequant-0:4.1.0-2.fc44.aa 100% | 36.6 MiB/s | 300.1 KiB | 00m00s [54/81] libjpeg-turbo-0:3.1.3-1.fc44.aa 100% | 49.1 MiB/s | 251.2 KiB | 00m00s [55/81] libraqm-0:0.10.1-4.fc44.aarch64 100% | 10.9 MiB/s | 22.4 KiB | 00m00s [56/81] libwebp-0:1.6.0-3.fc44.aarch64 100% | 84.7 MiB/s | 260.3 KiB | 00m00s [57/81] libxcb-0:1.17.0-7.fc44.aarch64 100% | 58.9 MiB/s | 241.3 KiB | 00m00s [58/81] openjpeg-0:2.5.4-3.fc44.aarch64 100% | 45.2 MiB/s | 185.2 KiB | 00m00s [59/81] python3-olefile-0:0.47-13.fc44. 100% | 36.6 MiB/s | 75.0 KiB | 00m00s [60/81] fribidi-0:1.0.16-4.fc44.aarch64 100% | 52.3 MiB/s | 53.6 KiB | 00m00s [61/81] libXau-0:1.0.12-4.fc44.aarch64 100% | 16.4 MiB/s | 33.7 KiB | 00m00s [62/81] fontconfig-0:2.17.0-4.fc44.aarc 100% | 89.2 MiB/s | 274.0 KiB | 00m00s [63/81] cairo-0:1.18.6-1.fc44.aarch64 100% | 137.2 MiB/s | 702.4 KiB | 00m00s [64/81] libXext-0:1.3.6-5.fc44.aarch64 100% | 9.4 MiB/s | 38.6 KiB | 00m00s [65/81] libXrender-0:0.9.12-4.fc44.aarc 100% | 13.1 MiB/s | 26.8 KiB | 00m00s [66/81] lzo-0:2.10-16.fc44.aarch64 100% | 31.6 MiB/s | 64.8 KiB | 00m00s [67/81] pixman-0:0.46.2-3.fc44.aarch64 100% | 69.2 MiB/s | 212.4 KiB | 00m00s [68/81] default-fonts-core-sans-0:4.3-1 100% | 9.5 MiB/s | 29.2 KiB | 00m00s [69/81] xml-common-0:0.6.3-68.fc44.noar 100% | 10.1 MiB/s | 31.1 KiB | 00m00s [70/81] abattis-cantarell-vf-fonts-0:0. 100% | 39.2 MiB/s | 120.4 KiB | 00m00s [71/81] google-noto-sans-vf-fonts-0:202 100% | 150.1 MiB/s | 614.9 KiB | 00m00s [72/81] harfbuzz-0:14.1.0-2.fc44.aarch6 100% | 174.9 MiB/s | 1.0 MiB | 00m00s [73/81] google-noto-fonts-common-0:2025 100% | 2.5 MiB/s | 17.7 KiB | 00m00s [74/81] libX11-0:1.8.13-3.fc44.aarch64 100% | 105.7 MiB/s | 649.6 KiB | 00m00s [75/81] libX11-common-0:1.8.13-3.fc44.n 100% | 28.5 MiB/s | 175.3 KiB | 00m00s [76/81] graphite2-0:1.3.14-20.fc44.aarc 100% | 9.0 MiB/s | 91.7 KiB | 00m00s [77/81] libtiff-0:4.7.2-3.fc44.aarch64 100% | 104.7 MiB/s | 214.5 KiB | 00m00s [78/81] jbigkit-libs-0:2.1-33.fc44.aarc 100% | 25.9 MiB/s | 53.1 KiB | 00m00s [79/81] liblerc-0:4.0.0-10.fc44.aarch64 100% | 63.2 MiB/s | 194.1 KiB | 00m00s [80/81] libpng-2:1.6.58-1.fc44.aarch64 100% | 115.0 MiB/s | 117.7 KiB | 00m00s [81/81] glib2-0:2.88.4-1.fc44.aarch64 100% | 204.1 MiB/s | 3.1 MiB | 00m00s -------------------------------------------------------------------------------- [81/81] Total 100% | 128.1 MiB/s | 26.4 MiB | 00m00s Running transaction [ 1/83] Verify package files 100% | 246.0 B/s | 81.0 B | 00m00s [ 2/83] Prepare transaction 100% | 540.0 B/s | 81.0 B | 00m00s [ 3/83] Installing libgfortran-0:16.2.1 100% | 342.3 MiB/s | 1.7 MiB | 00m00s [ 4/83] Installing fonts-filesystem-1:5 100% | 0.0 B/s | 788.0 B | 00m00s [ 5/83] Installing python-rpm-macros-0: 100% | 28.2 MiB/s | 28.9 KiB | 00m00s [ 6/83] Installing python3-rpm-macros-0 100% | 6.6 MiB/s | 6.8 KiB | 00m00s [ 7/83] Installing blas-0:3.12.0-11.fc4 100% | 95.5 MiB/s | 1.2 MiB | 00m00s [ 8/83] Installing libpng-2:1.6.58-1.fc 100% | 44.1 MiB/s | 271.0 KiB | 00m00s [ 9/83] Installing tzdata-0:2026e-1.fc4 100% | 27.2 MiB/s | 1.5 MiB | 00m00s [10/83] Installing libwebp-0:1.6.0-3.fc 100% | 200.4 MiB/s | 820.9 KiB | 00m00s [11/83] Installing libjpeg-turbo-0:3.1. 100% | 221.2 MiB/s | 679.4 KiB | 00m00s [12/83] Installing minizip-ng-compat-0: 100% | 194.6 MiB/s | 199.3 KiB | 00m00s [13/83] Installing libsbml-0:5.20.5-100 100% | 209.7 MiB/s | 9.9 MiB | 00m00s [14/83] Installing lapack-0:3.12.0-11.f 100% | 58.2 MiB/s | 16.1 MiB | 00m00s [15/83] Installing rr-libstruct-0:2.9.2 100% | 127.9 MiB/s | 261.9 KiB | 00m00s [16/83] Installing pyproject-rpm-macros 100% | 167.4 MiB/s | 171.5 KiB | 00m00s [17/83] Installing dejavu-sans-fonts-0: 100% | 367.2 MiB/s | 5.5 MiB | 00m00s [18/83] Installing abattis-cantarell-vf 100% | 94.9 MiB/s | 194.4 KiB | 00m00s [19/83] Installing glib2-0:2.88.4-1.fc4 100% | 248.6 MiB/s | 15.9 MiB | 00m00s [20/83] Installing python-pip-wheel-0:2 100% | 611.8 MiB/s | 1.2 MiB | 00m00s [21/83] Installing liblerc-0:4.0.0-10.f 100% | 267.5 MiB/s | 547.8 KiB | 00m00s [22/83] Installing jbigkit-libs-0:2.1-3 100% | 178.9 MiB/s | 183.2 KiB | 00m00s [23/83] Installing libtiff-0:4.7.2-3.fc 100% | 215.4 MiB/s | 661.7 KiB | 00m00s [24/83] Installing libX11-common-0:1.8. 100% | 91.2 MiB/s | 1.2 MiB | 00m00s [25/83] Installing graphite2-0:1.3.14-2 100% | 13.9 MiB/s | 241.5 KiB | 00m00s [26/83] Installing freetype-0:2.14.3-1. 100% | 214.9 MiB/s | 880.3 KiB | 00m00s [27/83] Installing harfbuzz-0:14.1.0-2. 100% | 296.9 MiB/s | 2.7 MiB | 00m00s [28/83] Installing libedit-0:3.1-59.202 100% | 137.7 MiB/s | 282.0 KiB | 00m00s [29/83] Installing llvm13-libs-0:13.0.1 100% | 417.2 MiB/s | 81.3 MiB | 00m00s [30/83] Installing google-noto-fonts-co 100% | 18.1 MiB/s | 18.5 KiB | 00m00s [31/83] Installing google-noto-sans-vf- 100% | 278.3 MiB/s | 1.4 MiB | 00m00s [32/83] Installing default-fonts-core-s 100% | 3.0 MiB/s | 18.2 KiB | 00m00s [33/83] Installing xml-common-0:0.6.3-6 100% | 39.6 MiB/s | 81.1 KiB | 00m00s [34/83] Installing fontconfig-0:2.17.0- 100% | 1.2 MiB/s | 1.2 MiB | 00m01s [35/83] Installing pixman-0:0.46.2-3.fc 100% | 213.4 MiB/s | 655.4 KiB | 00m00s [36/83] Installing lzo-0:2.10-16.fc44.a 100% | 160.6 MiB/s | 164.4 KiB | 00m00s [37/83] Installing libXau-0:1.0.12-4.fc 100% | 119.5 MiB/s | 122.3 KiB | 00m00s [38/83] Installing libxcb-0:1.17.0-7.fc 100% | 270.4 MiB/s | 2.2 MiB | 00m00s [39/83] Installing libX11-0:1.8.13-3.fc 100% | 268.6 MiB/s | 1.3 MiB | 00m00s [40/83] Installing libXext-0:1.3.6-5.fc 100% | 143.5 MiB/s | 147.0 KiB | 00m00s [41/83] Installing libXrender-0:0.9.12- 100% | 69.5 MiB/s | 71.1 KiB | 00m00s [42/83] Installing cairo-0:1.18.6-1.fc4 100% | 255.0 MiB/s | 1.8 MiB | 00m00s [43/83] Installing fribidi-0:1.0.16-4.f 100% | 13.5 MiB/s | 248.5 KiB | 00m00s [44/83] Installing libraqm-0:0.10.1-4.f 100% | 68.0 MiB/s | 69.6 KiB | 00m00s [45/83] Installing openjpeg-0:2.5.4-3.f 100% | 202.2 MiB/s | 414.2 KiB | 00m00s [46/83] Installing libimagequant-0:4.1. 100% | 219.3 MiB/s | 673.7 KiB | 00m00s [47/83] Installing lcms2-0:2.16-7.fc44. 100% | 237.5 MiB/s | 486.3 KiB | 00m00s [48/83] Installing openblas-0:0.3.29-2. 100% | 110.8 MiB/s | 113.5 KiB | 00m00s [49/83] Installing openblas-openmp-0:0. 100% | 433.8 MiB/s | 20.4 MiB | 00m00s [50/83] Installing flexiblas-netlib-0:3 100% | 253.5 MiB/s | 14.2 MiB | 00m00s [51/83] Installing flexiblas-0:3.5.0-2. 100% | 38.2 MiB/s | 39.2 KiB | 00m00s [52/83] Installing flexiblas-openblas-o 100% | 66.4 MiB/s | 68.0 KiB | 00m00s [53/83] Installing mpdecimal-0:4.0.1-3. 100% | 138.0 MiB/s | 282.6 KiB | 00m00s [54/83] Installing expat-0:2.8.5-1.fc44 100% | 15.8 MiB/s | 388.2 KiB | 00m00s [55/83] Installing python3-libs-0:3.14. 100% | 263.4 MiB/s | 46.1 MiB | 00m00s [56/83] Installing python3-0:3.14.8-1.f 100% | 4.7 MiB/s | 86.5 KiB | 00m00s [57/83] Installing python3-numpy-f2py-1 100% | 57.4 MiB/s | 2.2 MiB | 00m00s [58/83] Installing python3-numpy-1:2.4. 100% | 239.4 MiB/s | 36.6 MiB | 00m00s [59/83] Installing python3-packaging-0: 100% | 151.3 MiB/s | 619.9 KiB | 00m00s [60/83] Installing python3-rpm-generato 100% | 81.0 MiB/s | 82.9 KiB | 00m00s [61/83] Installing python3-contourpy-0: 100% | 170.6 MiB/s | 873.5 KiB | 00m00s [62/83] Installing python3-cairo-0:1.28 100% | 169.3 MiB/s | 520.1 KiB | 00m00s [63/83] Installing python3-cycler-0:0.1 100% | 39.3 MiB/s | 40.3 KiB | 00m00s [64/83] Installing python3-pyparsing-0: 100% | 205.9 MiB/s | 1.0 MiB | 00m00s [65/83] Installing python3-iniconfig-0: 100% | 26.4 MiB/s | 54.1 KiB | 00m00s [66/83] Installing python3-pluggy-0:1.6 100% | 42.6 MiB/s | 217.9 KiB | 00m00s [67/83] Installing python3-pygments-0:2 100% | 153.2 MiB/s | 11.5 MiB | 00m00s [68/83] Installing python3-six-0:1.17.0 100% | 117.5 MiB/s | 120.3 KiB | 00m00s [69/83] Installing python3-dateutil-1:2 100% | 108.8 MiB/s | 891.5 KiB | 00m00s [70/83] Installing python3-fonttools-0: 100% | 257.7 MiB/s | 19.6 MiB | 00m00s [71/83] Installing python3-kiwisolver-0 100% | 80.7 MiB/s | 165.2 KiB | 00m00s [72/83] Installing python3-olefile-0:0. 100% | 113.9 MiB/s | 349.8 KiB | 00m00s [73/83] Installing python3-pillow-0:12. 100% | 224.0 MiB/s | 4.7 MiB | 00m00s [74/83] Installing utf8proc-0:2.11.3-2. 100% | 202.6 MiB/s | 414.9 KiB | 00m00s [75/83] Installing poco-foundation-0:1. 100% | 315.7 MiB/s | 2.2 MiB | 00m00s [76/83] Installing poco-net-0:1.14.1-3. 100% | 277.5 MiB/s | 1.4 MiB | 00m00s [77/83] Installing python3-matplotlib-d 100% | 329.8 MiB/s | 7.9 MiB | 00m00s [78/83] Installing libqhull_r-1:8.0.2-8 100% | 89.1 MiB/s | 456.1 KiB | 00m00s [79/83] Installing python3-matplotlib-0 100% | 310.6 MiB/s | 32.0 MiB | 00m00s [80/83] Installing python3-roadrunner-0 100% | 343.8 MiB/s | 11.0 MiB | 00m00s [81/83] Installing python3-pytest-0:8.4 100% | 263.7 MiB/s | 22.7 MiB | 00m00s [82/83] Installing python3-devel-0:3.14 100% | 64.7 MiB/s | 2.0 MiB | 00m00s [83/83] Installing python3-libsbml-0:5. 100% | 213.2 MiB/s | 33.7 MiB | 00m00s Warning: skipped OpenPGP checks for 4 packages from repository: copr_base Complete! Building target platforms: aarch64 Building for target aarch64 setting SOURCE_DATE_EPOCH=1792713600 Wrote: /builddir/build/SRPMS/python-sbmlutils-0.17.0-1.fc44.src.rpm Updating and loading repositories: updates 100% | 52.9 KiB/s | 9.8 KiB | 00m00s fedora 100% | 54.9 KiB/s | 10.2 KiB | 00m00s Additional repo copr_mhough_neurofedor 100% | 12.9 KiB/s | 1.5 KiB | 00m00s Copr repository 100% | 12.7 KiB/s | 1.5 KiB | 00m00s Repositories loaded. Package "pyproject-rpm-macros-1.24.0-1.fc44.noarch" is already installed. Package "python3-devel-3.14.8-1.fc44.aarch64" is already installed. Package "python3-libsbml-5.20.5-100.fc44.biofedora.aarch64" is already installed. Package "python3-matplotlib-3.10.8-2.fc44.aarch64" is already installed. Package "python3-pytest-8.4.2-2.fc44.noarch" is already installed. Package "python3-roadrunner-2.10.0-11.fc44.aarch64" is already installed. Nothing to do. Finish: build setup for python-sbmlutils-0.17.0-1.fc44.src.rpm Start: rpmbuild python-sbmlutils-0.17.0-1.fc44.src.rpm Building target platforms: aarch64 Building for target aarch64 setting SOURCE_DATE_EPOCH=1792713600 Executing(%mkbuilddir): /bin/sh -e /var/tmp/rpm-tmp.DiGYay Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.FY4fYT + umask 022 + cd /builddir/build/BUILD/python-sbmlutils-0.17.0-build + cd /builddir/build/BUILD/python-sbmlutils-0.17.0-build + rm -rf sbmlutils-0.17.0 + /usr/lib/rpm/rpmuncompress -x /builddir/build/SOURCES/sbmlutils-0.17.0.tar.gz + STATUS=0 + '[' 0 -ne 0 ']' + cd sbmlutils-0.17.0 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + grep -qP '^\t"python-libsbml>=5\.21\.2",$' pyproject.toml + sed -i '/^\t"python-libsbml>=5\.21\.2",$/d' pyproject.toml + for d in 'pint>=0.25.3:pint>=0.25' 'xmltodict>=1.0.2:xmltodict>=0.14' 'certifi>=2026.10.19:certifi>=2025' + old='pint>=0.25.3' + new='pint>=0.25' + grep -qP '^\t"pint>=0.25.3",$' pyproject.toml + sed -i 's/^\t"pint>=0.25.3",$/\t"pint>=0.25",/' pyproject.toml + for d in 'pint>=0.25.3:pint>=0.25' 'xmltodict>=1.0.2:xmltodict>=0.14' 'certifi>=2026.10.19:certifi>=2025' + old='xmltodict>=1.0.2' + new='xmltodict>=0.14' + grep -qP '^\t"xmltodict>=1.0.2",$' pyproject.toml + sed -i 's/^\t"xmltodict>=1.0.2",$/\t"xmltodict>=0.14",/' pyproject.toml + for d in 'pint>=0.25.3:pint>=0.25' 'xmltodict>=1.0.2:xmltodict>=0.14' 'certifi>=2026.10.19:certifi>=2025' + old='certifi>=2026.10.19' + new='certifi>=2025' + grep -qP '^\t"certifi>=2026.10.19",$' pyproject.toml + sed -i 's/^\t"certifi>=2026.10.19",$/\t"certifi>=2025",/' pyproject.toml + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.BqdjCe + umask 022 + cd /builddir/build/BUILD/python-sbmlutils-0.17.0-build + cd sbmlutils-0.17.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(packaging)' + echo 'python3dist(pip) >= 19' + '[' -f pyproject.toml ']' + echo '(python3dist(tomli) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + echo -n + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + RPM_TOXENV=py314 + FEDORA=44 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/python-sbmlutils-0.17.0-build/pyproject-wheeldir --output /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-buildrequires --dep-overrides-file /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-dep-overrides Handling hatchling from build-system.requires Requirement not satisfied: hatchling Exiting dependency generation pass: build backend + cat /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-buildrequires + rm -rfv '*.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-sbmlutils-0.17.0-1.fc44.buildreqs.nosrc.rpm INFO: Going to install missing dynamic buildrequires Updating and loading repositories: updates 100% | 37.1 KiB/s | 9.8 KiB | 00m00s fedora 100% | 38.3 KiB/s | 10.2 KiB | 00m00s Additional repo copr_mhough_neurofedor 100% | 10.3 KiB/s | 1.5 KiB | 00m00s Copr repository 100% | 10.2 KiB/s | 1.5 KiB | 00m00s Repositories loaded. Package "pyproject-rpm-macros-1.24.0-1.fc44.noarch" is already installed. Package "python3-devel-3.14.8-1.fc44.aarch64" is already installed. Package "python3-libsbml-5.20.5-100.fc44.biofedora.aarch64" is already installed. Package "python3-matplotlib-3.10.8-2.fc44.aarch64" is already installed. Package "python3-pytest-8.4.2-2.fc44.noarch" is already installed. Package "python3-roadrunner-2.10.0-11.fc44.aarch64" is already installed. Package "python3-packaging-25.0-8.fc44.noarch" is already installed. Package Arch Version Repository Size Installing: python3-hatchling noarch 0:1.31.0-1.fc44 updates 681.6 KiB python3-pip noarch 0:26.0.1-3.fc44 updates 11.5 MiB Installing dependencies: python3-pathspec noarch 0:1.0.3-2.fc44 fedora 372.4 KiB python3-trove-classifiers noarch 0:2026.1.14.14-2.fc44 fedora 111.9 KiB Transaction Summary: Installing: 4 packages Total size of inbound packages is 3 MiB. Need to download 0 B. After this operation, 13 MiB extra will be used (install 13 MiB, remove 0 B). [1/4] python3-hatchling-0:1.31.0-1.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [2/4] python3-pip-0:26.0.1-3.fc44.noarc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [3/4] python3-pathspec-0:1.0.3-2.fc44.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [4/4] python3-trove-classifiers-0:2026. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded -------------------------------------------------------------------------------- [4/4] Total 100% | 0.0 B/s | 0.0 B | 00m00s Running transaction [1/6] Verify package files 100% | 400.0 B/s | 4.0 B | 00m00s [2/6] Prepare transaction 100% | 117.0 B/s | 4.0 B | 00m00s [3/6] Installing python3-trove-classifi 100% | 6.3 MiB/s | 115.7 KiB | 00m00s [4/6] Installing python3-pathspec-0:1.0 100% | 64.2 MiB/s | 394.6 KiB | 00m00s [5/6] Installing python3-hatchling-0:1. 100% | 23.8 MiB/s | 730.8 KiB | 00m00s [6/6] Installing python3-pip-0:26.0.1-3 100% | 102.9 MiB/s | 11.7 MiB | 00m00s Complete! Building target platforms: aarch64 Building for target aarch64 setting SOURCE_DATE_EPOCH=1792713600 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.da8nul + umask 022 + cd /builddir/build/BUILD/python-sbmlutils-0.17.0-build + cd sbmlutils-0.17.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(packaging)' + echo 'python3dist(pip) >= 19' + '[' -f pyproject.toml ']' + echo '(python3dist(tomli) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + echo -n + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + RPM_TOXENV=py314 + FEDORA=44 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/python-sbmlutils-0.17.0-build/pyproject-wheeldir --output /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-buildrequires --dep-overrides-file /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-dep-overrides Handling hatchling from build-system.requires Requirement satisfied: hatchling (installed: hatchling 1.31.0) Handling antimony!=3.2.0; sys_platform == 'win32' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: antimony!=3.2.0; sys_platform == 'win32' Handling antimony>=3.1.3 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: antimony>=3.1.3 Handling certifi>=2025 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: certifi>=2025 Handling jinja2>=3.1.6 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: jinja2>=3.1.6 Handling lxml>=6.1.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: lxml>=6.1.0 Handling markdown-it-py>=3.0.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: markdown-it-py>=3.0.0 Handling numpy>=2.2.2 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: numpy>=2.2.2 (installed: numpy 2.4.6) Handling openpyxl>=3.1.5 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: openpyxl>=3.1.5 Handling pandas>=2.2.2 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: pandas>=2.2.2 Handling pint>=0.25 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: pint>=0.25 Handling pymetadata>=0.8.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: pymetadata>=0.8.0 Handling requests>=2.32.4 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: requests>=2.32.4 Handling rich>=13.0.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: rich>=13.0.0 Handling sbmlode>=0.2.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: sbmlode>=0.2.0 Handling xmltodict>=0.14 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: xmltodict>=0.14 Handling cobra>=0.32.1; extra == 'cobra' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: cobra>=0.32.1; extra == 'cobra' Handling py4cytoscape>=1.13.0; extra == 'cytoscape' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: py4cytoscape>=1.13.0; extra == 'cytoscape' Handling bump-my-version>=1.5.1; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: bump-my-version>=1.5.1; extra == 'dev' Handling libroadrunner>=2.10.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: libroadrunner>=2.10.0; extra == 'dev' Handling matplotlib>=3.11.1; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: matplotlib>=3.11.1; extra == 'dev' Handling mkdocstrings-python>=2.0.8; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: mkdocstrings-python>=2.0.8; extra == 'dev' Handling pre-commit>=4.6.2; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pre-commit>=4.6.2; extra == 'dev' Handling py4cytoscape>=1.13.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: py4cytoscape>=1.13.0; extra == 'dev' Handling pytest-cov>=7.1.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pytest-cov>=7.1.0; extra == 'dev' Handling pytest-xdist>=3.8.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pytest-xdist>=3.8.0; extra == 'dev' Handling pytest>=9.1.1; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pytest>=9.1.1; extra == 'dev' Handling ruff>=0.16.6; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: ruff>=0.16.6; extra == 'dev' Handling tox>=4.61.2; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: tox>=4.61.2; extra == 'dev' Handling ty>=0.0.79; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: ty>=0.0.79; extra == 'dev' Handling zensical>=0.0.60; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: zensical>=0.0.60; extra == 'dev' Handling libroadrunner>=2.10.0; extra == 'examples' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: libroadrunner>=2.10.0; extra == 'examples' Handling matplotlib>=3.11.1; extra == 'examples' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: matplotlib>=3.11.1; extra == 'examples' + cat /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-buildrequires + rm -rfv sbmlutils-0.17.0.dist-info/ removed 'sbmlutils-0.17.0.dist-info/METADATA' removed directory 'sbmlutils-0.17.0.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-sbmlutils-0.17.0-1.fc44.buildreqs.nosrc.rpm INFO: Going to install missing dynamic buildrequires Updating and loading repositories: updates 100% | 50.7 KiB/s | 9.8 KiB | 00m00s fedora 100% | 52.6 KiB/s | 10.2 KiB | 00m00s Additional repo copr_mhough_neurofedor 100% | 12.2 KiB/s | 1.5 KiB | 00m00s Copr repository 100% | 12.2 KiB/s | 1.5 KiB | 00m00s Repositories loaded. Package "pyproject-rpm-macros-1.24.0-1.fc44.noarch" is already installed. Package "python3-devel-3.14.8-1.fc44.aarch64" is already installed. Package "python3-libsbml-5.20.5-100.fc44.biofedora.aarch64" is already installed. Package "python3-matplotlib-3.10.8-2.fc44.aarch64" is already installed. Package "python3-pytest-8.4.2-2.fc44.noarch" is already installed. Package "python3-roadrunner-2.10.0-11.fc44.aarch64" is already installed. Package "python3-hatchling-1.31.0-1.fc44.noarch" is already installed. Package "python3-numpy-1:2.4.6-1.fc44.aarch64" is already installed. Package "python3-packaging-25.0-8.fc44.noarch" is already installed. Package "python3-pip-26.0.1-3.fc44.noarch" is already installed. Package Arch Version Repository Size Installing: python3-antimony aarch64 0:3.2.1-1.fc44 copr_base 1.9 MiB python3-certifi noarch 0:2026.01.04-1.fc44 fedora 7.4 KiB python3-jinja2 noarch 0:3.1.6-7.fc44 fedora 3.1 MiB python3-lxml aarch64 0:6.1.1-1.fc44 updates 5.7 MiB python3-markdown-it-py noarch 0:3.0.0-14.fc44 fedora 541.5 KiB python3-openpyxl noarch 0:3.1.5-5.fc44 fedora 1.9 MiB python3-pandas aarch64 0:2.3.3-3.fc44 fedora 40.2 MiB python3-pint noarch 0:0.25.2-2.fc44 fedora 3.4 MiB python3-pymetadata noarch 0:0.8.2-1.fc44 copr_base 2.9 MiB python3-requests noarch 0:2.33.1-1.fc44 updates 477.3 KiB python3-rich noarch 0:14.3.2-1.fc44 fedora 3.4 MiB python3-sbmlode noarch 0:0.3.1-1.fc44 copr_base 895.1 KiB python3-xmltodict noarch 0:0.14.2-5.fc44 fedora 56.0 KiB Installing dependencies: libsbmlnetwork aarch64 0:0.5.12-2.fc44 copr_base 3.3 MiB libxslt aarch64 0:1.1.43-6.fc44 fedora 547.8 KiB python3-Bottleneck aarch64 0:1.6.0-2.fc44 fedora 709.1 KiB python3-annotated-types noarch 0:0.7.0-9.fc44 fedora 85.1 KiB python3-charset-normalizer noarch 0:3.4.4-2.fc44 fedora 356.2 KiB python3-et_xmlfile noarch 0:2.0.0-7.fc44 fedora 100.3 KiB python3-flexcache noarch 0:0.3-11.fc44 fedora 57.0 KiB python3-flexparser noarch 0:0.4-7.fc44 fedora 263.5 KiB python3-idna noarch 0:3.18-1.fc44 updates 522.3 KiB python3-markupsafe aarch64 0:3.0.2-7.fc44 fedora 117.4 KiB python3-mdurl noarch 0:0.1.2-14.fc44 fedora 44.0 KiB python3-numexpr aarch64 0:2.14.1-1.fc44 fedora 887.5 KiB python3-platformdirs noarch 0:4.9.1-1.fc44 fedora 236.5 KiB python3-pydantic noarch 0:2.12.5-4.fc44 updates 5.1 MiB python3-pydantic-core aarch64 0:2.41.5-11.fc44 updates 4.9 MiB python3-pytz noarch 0:2026.5-1.fc44 updates 228.2 KiB python3-typing-extensions noarch 0:4.16.0-4.fc44 updates 552.0 KiB python3-typing-inspection noarch 0:0.4.4-1.fc44 updates 93.4 KiB python3-urllib3 noarch 0:2.8.0-3.fc44 updates 1.2 MiB Transaction Summary: Installing: 32 packages Total size of inbound packages is 18 MiB. Need to download 7 MiB. After this operation, 84 MiB extra will be used (install 84 MiB, remove 0 B). [ 1/32] python3-jinja2-0:3.1.6-7.fc44.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 2/32] python3-markdown-it-py-0:3.0.0- 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 3/32] python3-pandas-0:2.3.3-3.fc44.a 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 4/32] python3-antimony-0:3.2.1-1.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 5/32] python3-requests-0:2.33.1-1.fc4 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 6/32] python3-markupsafe-0:3.0.2-7.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 7/32] python3-mdurl-0:0.1.2-14.fc44.n 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 8/32] python3-Bottleneck-0:1.6.0-2.fc 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [ 9/32] python3-numexpr-0:2.14.1-1.fc44 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [10/32] python3-platformdirs-0:4.9.1-1. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [11/32] libsbmlnetwork-0:0.5.12-2.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [12/32] python3-charset-normalizer-0:3. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [13/32] python3-urllib3-0:2.8.0-3.fc44. 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [14/32] python3-pytz-0:2026.5-1.fc44.no 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [15/32] python3-idna-0:3.18-1.fc44.noar 100% | 0.0 B/s | 0.0 B | 00m00s >>> Already downloaded [16/32] python3-certifi-0:2026.01.04-1. 100% | 1.1 MiB/s | 14.9 KiB | 00m00s [17/32] python3-openpyxl-0:3.1.5-5.fc44 100% | 35.4 MiB/s | 616.1 KiB | 00m00s [18/32] python3-lxml-0:6.1.1-1.fc44.aar 100% | 59.0 MiB/s | 1.5 MiB | 00m00s [19/32] python3-rich-0:14.3.2-1.fc44.no 100% | 32.4 MiB/s | 663.8 KiB | 00m00s [20/32] python3-pint-0:0.25.2-2.fc44.no 100% | 26.8 MiB/s | 740.8 KiB | 00m00s [21/32] python3-xmltodict-0:0.14.2-5.fc 100% | 6.5 MiB/s | 26.7 KiB | 00m00s [22/32] libxslt-0:1.1.43-6.fc44.aarch64 100% | 35.7 MiB/s | 182.9 KiB | 00m00s [23/32] python3-et_xmlfile-0:2.0.0-7.fc 100% | 14.8 MiB/s | 45.4 KiB | 00m00s [24/32] python3-flexcache-0:0.3-11.fc44 100% | 8.9 MiB/s | 27.2 KiB | 00m00s [25/32] python3-flexparser-0:0.4-7.fc44 100% | 17.9 MiB/s | 54.9 KiB | 00m00s [26/32] python3-pydantic-0:2.12.5-4.fc4 100% | 39.7 MiB/s | 1.0 MiB | 00m00s [27/32] python3-annotated-types-0:0.7.0 100% | 10.2 MiB/s | 31.4 KiB | 00m00s [28/32] python3-typing-extensions-0:4.1 100% | 37.2 MiB/s | 114.1 KiB | 00m00s [29/32] python3-pydantic-core-0:2.41.5- 100% | 133.0 MiB/s | 1.6 MiB | 00m00s [30/32] python3-typing-inspection-0:0.4 100% | 11.0 MiB/s | 33.7 KiB | 00m00s [31/32] python3-sbmlode-0:0.3.1-1.fc44. 100% | 1.0 MiB/s | 230.9 KiB | 00m00s [32/32] python3-pymetadata-0:0.8.2-1.fc 100% | 1.1 MiB/s | 374.9 KiB | 00m00s -------------------------------------------------------------------------------- [32/32] Total 100% | 18.7 MiB/s | 7.2 MiB | 00m00s Running transaction [ 1/34] Verify package files 100% | 533.0 B/s | 32.0 B | 00m00s [ 2/34] Prepare transaction 100% | 507.0 B/s | 32.0 B | 00m00s [ 3/34] Installing python3-typing-exten 100% | 180.4 MiB/s | 554.3 KiB | 00m00s [ 4/34] Installing python3-idna-0:3.18- 100% | 25.9 MiB/s | 530.2 KiB | 00m00s [ 5/34] Installing python3-urllib3-0:2. 100% | 147.5 MiB/s | 1.2 MiB | 00m00s [ 6/34] Installing python3-flexcache-0: 100% | 59.2 MiB/s | 60.6 KiB | 00m00s [ 7/34] Installing python3-flexparser-0 100% | 130.4 MiB/s | 267.1 KiB | 00m00s [ 8/34] Installing python3-pydantic-cor 100% | 307.8 MiB/s | 4.9 MiB | 00m00s [ 9/34] Installing python3-typing-inspe 100% | 47.6 MiB/s | 97.5 KiB | 00m00s [10/34] Installing python3-pytz-0:2026. 100% | 114.0 MiB/s | 233.6 KiB | 00m00s [11/34] Installing python3-annotated-ty 100% | 43.1 MiB/s | 88.2 KiB | 00m00s [12/34] Installing python3-pydantic-0:2 100% | 233.3 MiB/s | 5.1 MiB | 00m00s [13/34] Installing python3-charset-norm 100% | 18.8 MiB/s | 366.4 KiB | 00m00s [14/34] Installing python3-requests-0:2 100% | 119.5 MiB/s | 489.5 KiB | 00m00s [15/34] Installing libsbmlnetwork-0:0.5 100% | 465.8 MiB/s | 3.3 MiB | 00m00s [16/34] Installing python3-platformdirs 100% | 118.9 MiB/s | 243.4 KiB | 00m00s [17/34] Installing python3-numexpr-0:2. 100% | 146.4 MiB/s | 899.2 KiB | 00m00s [18/34] Installing python3-Bottleneck-0 100% | 102.1 MiB/s | 731.8 KiB | 00m00s [19/34] Installing python3-mdurl-0:0.1. 100% | 24.1 MiB/s | 49.4 KiB | 00m00s [20/34] Installing python3-markdown-it- 100% | 22.0 MiB/s | 585.7 KiB | 00m00s [21/34] Installing python3-rich-0:14.3. 100% | 193.1 MiB/s | 3.5 MiB | 00m00s [22/34] Installing libxslt-0:1.1.43-6.f 100% | 28.3 MiB/s | 550.9 KiB | 00m00s [23/34] Installing python3-lxml-0:6.1.1 100% | 259.9 MiB/s | 5.7 MiB | 00m00s [24/34] Installing python3-et_xmlfile-0 100% | 51.5 MiB/s | 105.5 KiB | 00m00s [25/34] Installing python3-markupsafe-0 100% | 59.4 MiB/s | 121.7 KiB | 00m00s [26/34] Installing python3-jinja2-0:3.1 100% | 257.6 MiB/s | 3.1 MiB | 00m00s [27/34] Installing python3-certifi-0:20 100% | 10.9 MiB/s | 11.2 KiB | 00m00s [28/34] Installing python3-pymetadata-0 100% | 296.3 MiB/s | 3.0 MiB | 00m00s [29/34] Installing python3-sbmlode-0:0. 100% | 127.0 MiB/s | 910.5 KiB | 00m00s [30/34] Installing python3-openpyxl-0:3 100% | 74.2 MiB/s | 2.0 MiB | 00m00s [31/34] Installing python3-pandas-0:2.3 100% | 299.6 MiB/s | 40.4 MiB | 00m00s [32/34] Installing python3-pint-0:0.25. 100% | 93.7 MiB/s | 3.5 MiB | 00m00s [33/34] Installing python3-antimony-0:3 100% | 311.7 MiB/s | 1.9 MiB | 00m00s [34/34] Installing python3-xmltodict-0: 100% | 1.8 MiB/s | 58.5 KiB | 00m00s Warning: skipped OpenPGP checks for 4 packages from repository: copr_base Complete! Building target platforms: aarch64 Building for target aarch64 setting SOURCE_DATE_EPOCH=1792713600 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.zQo0Sf + umask 022 + cd /builddir/build/BUILD/python-sbmlutils-0.17.0-build + cd sbmlutils-0.17.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(packaging)' + echo 'python3dist(pip) >= 19' + '[' -f pyproject.toml ']' + echo '(python3dist(tomli) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + echo -n + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + RPM_TOXENV=py314 + FEDORA=44 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/python-sbmlutils-0.17.0-build/pyproject-wheeldir --output /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-buildrequires --dep-overrides-file /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-dep-overrides Handling hatchling from build-system.requires Requirement satisfied: hatchling (installed: hatchling 1.31.0) Handling antimony!=3.2.0; sys_platform == 'win32' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: antimony!=3.2.0; sys_platform == 'win32' Handling antimony>=3.1.3 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: antimony>=3.1.3 Handling certifi>=2025 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: certifi>=2025 (installed: certifi 2026.1.4) Handling jinja2>=3.1.6 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: jinja2>=3.1.6 (installed: jinja2 3.1.6) Handling lxml>=6.1.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: lxml>=6.1.0 (installed: lxml 6.1.1) Handling markdown-it-py>=3.0.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: markdown-it-py>=3.0.0 (installed: markdown-it-py 3.0.0) Handling numpy>=2.2.2 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: numpy>=2.2.2 (installed: numpy 2.4.6) Handling openpyxl>=3.1.5 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: openpyxl>=3.1.5 (installed: openpyxl 3.1.5) Handling pandas>=2.2.2 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: pandas>=2.2.2 (installed: pandas 2.3.3) Handling pint>=0.25 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: pint>=0.25 (installed: pint 0.25.2) Handling pymetadata>=0.8.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: pymetadata>=0.8.0 (installed: pymetadata 0.8.2) Handling requests>=2.32.4 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: requests>=2.32.4 (installed: requests 2.33.1) Handling rich>=13.0.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: rich>=13.0.0 (installed: rich 14.3.2) Handling sbmlode>=0.2.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: sbmlode>=0.2.0 (installed: sbmlode 0.3.1) Handling xmltodict>=0.14 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: xmltodict>=0.14 (installed: xmltodict 0.14.2) Handling cobra>=0.32.1; extra == 'cobra' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: cobra>=0.32.1; extra == 'cobra' Handling py4cytoscape>=1.13.0; extra == 'cytoscape' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: py4cytoscape>=1.13.0; extra == 'cytoscape' Handling bump-my-version>=1.5.1; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: bump-my-version>=1.5.1; extra == 'dev' Handling libroadrunner>=2.10.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: libroadrunner>=2.10.0; extra == 'dev' Handling matplotlib>=3.11.1; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: matplotlib>=3.11.1; extra == 'dev' Handling mkdocstrings-python>=2.0.8; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: mkdocstrings-python>=2.0.8; extra == 'dev' Handling pre-commit>=4.6.2; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pre-commit>=4.6.2; extra == 'dev' Handling py4cytoscape>=1.13.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: py4cytoscape>=1.13.0; extra == 'dev' Handling pytest-cov>=7.1.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pytest-cov>=7.1.0; extra == 'dev' Handling pytest-xdist>=3.8.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pytest-xdist>=3.8.0; extra == 'dev' Handling pytest>=9.1.1; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pytest>=9.1.1; extra == 'dev' Handling ruff>=0.16.6; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: ruff>=0.16.6; extra == 'dev' Handling tox>=4.61.2; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: tox>=4.61.2; extra == 'dev' Handling ty>=0.0.79; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: ty>=0.0.79; extra == 'dev' Handling zensical>=0.0.60; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: zensical>=0.0.60; extra == 'dev' Handling libroadrunner>=2.10.0; extra == 'examples' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: libroadrunner>=2.10.0; extra == 'examples' Handling matplotlib>=3.11.1; extra == 'examples' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: matplotlib>=3.11.1; extra == 'examples' + cat /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-buildrequires + rm -rfv sbmlutils-0.17.0.dist-info/ removed 'sbmlutils-0.17.0.dist-info/METADATA' removed directory 'sbmlutils-0.17.0.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-sbmlutils-0.17.0-1.fc44.buildreqs.nosrc.rpm INFO: Going to install missing dynamic buildrequires Updating and loading repositories: updates 100% | 61.2 KiB/s | 9.8 KiB | 00m00s fedora 100% | 63.5 KiB/s | 10.2 KiB | 00m00s Additional repo copr_mhough_neurofedor 100% | 11.6 KiB/s | 1.5 KiB | 00m00s Copr repository 100% | 11.5 KiB/s | 1.5 KiB | 00m00s Repositories loaded. Package "pyproject-rpm-macros-1.24.0-1.fc44.noarch" is already installed. Package "python3-devel-3.14.8-1.fc44.aarch64" is already installed. Package "python3-libsbml-5.20.5-100.fc44.biofedora.aarch64" is already installed. Package "python3-matplotlib-3.10.8-2.fc44.aarch64" is already installed. Package "python3-pytest-8.4.2-2.fc44.noarch" is already installed. Package "python3-roadrunner-2.10.0-11.fc44.aarch64" is already installed. Package "python3-antimony-3.2.1-1.fc44.aarch64" is already installed. Package "python3-certifi-2026.01.04-1.fc44.noarch" is already installed. Package "python3-hatchling-1.31.0-1.fc44.noarch" is already installed. Package "python3-jinja2-3.1.6-7.fc44.noarch" is already installed. Package "python3-lxml-6.1.1-1.fc44.aarch64" is already installed. Package "python3-markdown-it-py-3.0.0-14.fc44.noarch" is already installed. Package "python3-numpy-1:2.4.6-1.fc44.aarch64" is already installed. Package "python3-openpyxl-3.1.5-5.fc44.noarch" is already installed. Package "python3-packaging-25.0-8.fc44.noarch" is already installed. Package "python3-pandas-2.3.3-3.fc44.aarch64" is already installed. Package "python3-pint-0.25.2-2.fc44.noarch" is already installed. Package "python3-pip-26.0.1-3.fc44.noarch" is already installed. Package "python3-pymetadata-0.8.2-1.fc44.noarch" is already installed. Package "python3-requests-2.33.1-1.fc44.noarch" is already installed. Package "python3-rich-14.3.2-1.fc44.noarch" is already installed. Package "python3-sbmlode-0.3.1-1.fc44.noarch" is already installed. Package "python3-xmltodict-0.14.2-5.fc44.noarch" is already installed. Nothing to do. Building target platforms: aarch64 Building for target aarch64 setting SOURCE_DATE_EPOCH=1792713600 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.44c35g + umask 022 + cd /builddir/build/BUILD/python-sbmlutils-0.17.0-build + cd sbmlutils-0.17.0 + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(packaging)' + echo 'python3dist(pip) >= 19' + '[' -f pyproject.toml ']' + echo '(python3dist(tomli) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + echo -n + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + RPM_TOXENV=py314 + FEDORA=44 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/python-sbmlutils-0.17.0-build/pyproject-wheeldir --output /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-buildrequires --dep-overrides-file /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-dep-overrides Handling hatchling from build-system.requires Requirement satisfied: hatchling (installed: hatchling 1.31.0) Handling antimony!=3.2.0; sys_platform == 'win32' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: antimony!=3.2.0; sys_platform == 'win32' Handling antimony>=3.1.3 from hook generated metadata: Requires-Dist (sbmlutils) Requirement not satisfied: antimony>=3.1.3 Handling certifi>=2025 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: certifi>=2025 (installed: certifi 2026.1.4) Handling jinja2>=3.1.6 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: jinja2>=3.1.6 (installed: jinja2 3.1.6) Handling lxml>=6.1.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: lxml>=6.1.0 (installed: lxml 6.1.1) Handling markdown-it-py>=3.0.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: markdown-it-py>=3.0.0 (installed: markdown-it-py 3.0.0) Handling numpy>=2.2.2 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: numpy>=2.2.2 (installed: numpy 2.4.6) Handling openpyxl>=3.1.5 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: openpyxl>=3.1.5 (installed: openpyxl 3.1.5) Handling pandas>=2.2.2 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: pandas>=2.2.2 (installed: pandas 2.3.3) Handling pint>=0.25 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: pint>=0.25 (installed: pint 0.25.2) Handling pymetadata>=0.8.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: pymetadata>=0.8.0 (installed: pymetadata 0.8.2) Handling requests>=2.32.4 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: requests>=2.32.4 (installed: requests 2.33.1) Handling rich>=13.0.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: rich>=13.0.0 (installed: rich 14.3.2) Handling sbmlode>=0.2.0 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: sbmlode>=0.2.0 (installed: sbmlode 0.3.1) Handling xmltodict>=0.14 from hook generated metadata: Requires-Dist (sbmlutils) Requirement satisfied: xmltodict>=0.14 (installed: xmltodict 0.14.2) Handling cobra>=0.32.1; extra == 'cobra' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: cobra>=0.32.1; extra == 'cobra' Handling py4cytoscape>=1.13.0; extra == 'cytoscape' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: py4cytoscape>=1.13.0; extra == 'cytoscape' Handling bump-my-version>=1.5.1; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: bump-my-version>=1.5.1; extra == 'dev' Handling libroadrunner>=2.10.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: libroadrunner>=2.10.0; extra == 'dev' Handling matplotlib>=3.11.1; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: matplotlib>=3.11.1; extra == 'dev' Handling mkdocstrings-python>=2.0.8; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: mkdocstrings-python>=2.0.8; extra == 'dev' Handling pre-commit>=4.6.2; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pre-commit>=4.6.2; extra == 'dev' Handling py4cytoscape>=1.13.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: py4cytoscape>=1.13.0; extra == 'dev' Handling pytest-cov>=7.1.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pytest-cov>=7.1.0; extra == 'dev' Handling pytest-xdist>=3.8.0; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pytest-xdist>=3.8.0; extra == 'dev' Handling pytest>=9.1.1; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: pytest>=9.1.1; extra == 'dev' Handling ruff>=0.16.6; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: ruff>=0.16.6; extra == 'dev' Handling tox>=4.61.2; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: tox>=4.61.2; extra == 'dev' Handling ty>=0.0.79; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: ty>=0.0.79; extra == 'dev' Handling zensical>=0.0.60; extra == 'dev' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: zensical>=0.0.60; extra == 'dev' Handling libroadrunner>=2.10.0; extra == 'examples' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: libroadrunner>=2.10.0; extra == 'examples' Handling matplotlib>=3.11.1; extra == 'examples' from hook generated metadata: Requires-Dist (sbmlutils) Ignoring alien requirement: matplotlib>=3.11.1; extra == 'examples' + cat /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-buildrequires + rm -rfv sbmlutils-0.17.0.dist-info/ removed 'sbmlutils-0.17.0.dist-info/METADATA' removed directory 'sbmlutils-0.17.0.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.z64A5y + umask 022 + cd /builddir/build/BUILD/python-sbmlutils-0.17.0-build + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FCFLAGS + VALAFLAGS=-g + export VALAFLAGS + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd sbmlutils-0.17.0 + mkdir -p /builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + VALAFLAGS=-g + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + LT_SYS_LIBRARY_PATH=/usr/lib64: + CC=gcc + CXX=g++ + TMPDIR=/builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_wheel.py /builddir/build/BUILD/python-sbmlutils-0.17.0-build/pyproject-wheeldir Processing ./. Preparing metadata (pyproject.toml): started Running command Preparing metadata (pyproject.toml) Preparing metadata (pyproject.toml): finished with status 'done' Building wheels for collected packages: sbmlutils Building wheel for sbmlutils (pyproject.toml): started Running command Building wheel for sbmlutils (pyproject.toml) Building wheel for sbmlutils (pyproject.toml): finished with status 'done' Created wheel for sbmlutils: filename=sbmlutils-0.17.0-py3-none-any.whl size=3633279 sha256=436ce409b1f1bae4f6afe66c534b837077da714b185049c3d57f98bc2ca084fa Stored in directory: /builddir/.cache/pip/wheels/b8/c9/e2/df1ef8885d97c39647586eef9f2cba9beca56d30bd6d8cd270 Successfully built sbmlutils + RPM_EC=0 ++ jobs -p + exit 0 Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.g4wqOK + umask 022 + cd /builddir/build/BUILD/python-sbmlutils-0.17.0-build + '[' /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT '!=' / ']' + rm -rf /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT ++ dirname /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT + mkdir -p /builddir/build/BUILD/python-sbmlutils-0.17.0-build + mkdir /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FCFLAGS + VALAFLAGS=-g + export VALAFLAGS + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd sbmlutils-0.17.0 ++ ls /builddir/build/BUILD/python-sbmlutils-0.17.0-build/pyproject-wheeldir/sbmlutils-0.17.0-py3-none-any.whl ++ xargs basename --multiple ++ sed -E 's/([^-]+)-([^-]+)-.+\.whl/\1==\2/' + specifier=sbmlutils==0.17.0 + '[' -z sbmlutils==0.17.0 ']' + PIP_CONFIG_FILE=/dev/null + TMPDIR=/builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir + /usr/bin/python3 -m pip install --root /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT --prefix /usr --no-deps --disable-pip-version-check --progress-bar off --verbose --ignore-installed --no-warn-script-location --no-index --no-cache-dir --find-links /builddir/build/BUILD/python-sbmlutils-0.17.0-build/pyproject-wheeldir sbmlutils==0.17.0 Using pip 26.0.1 from /usr/lib/python3.14/site-packages/pip (python 3.14) Looking in links: /builddir/build/BUILD/python-sbmlutils-0.17.0-build/pyproject-wheeldir Processing /builddir/build/BUILD/python-sbmlutils-0.17.0-build/pyproject-wheeldir/sbmlutils-0.17.0-py3-none-any.whl Installing collected packages: sbmlutils Successfully installed sbmlutils-0.17.0 + '[' -d /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/bin ']' + rm -f /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-ghost-distinfo + site_dirs=() + '[' -d /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages ']' + site_dirs+=("/usr/lib/python3.14/site-packages") + '[' /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib64/python3.14/site-packages '!=' /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages ']' + '[' -d /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib64/python3.14/site-packages ']' + for site_dir in ${site_dirs[@]} + for distinfo in /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT$site_dir/*.dist-info + echo '%ghost %dir /usr/lib/python3.14/site-packages/sbmlutils-0.17.0.dist-info' +++ basename /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils-0.17.0.dist-info ++ PYTHONPATH=/usr/lib/rpm/redhat ++ /usr/bin/python3 -sBc 'import sys; from pyproject_save_files import canonical_name_from_distinfo; print(canonical_name_from_distinfo(sys.argv[1]))' sbmlutils-0.17.0.dist-info + _normalized=sbmlutils + echo '%ghost %dir /usr/lib/python3.14/site-packages/sbmlutils-0.17.0.dist-info' + sed -i s/pip/rpm/ /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils-0.17.0.dist-info/INSTALLER + PYTHONPATH=/usr/lib/rpm/redhat + /usr/bin/python3 -B /usr/lib/rpm/redhat/pyproject_preprocess_record.py --buildroot /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT --record /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils-0.17.0.dist-info/RECORD --output /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-record + rm -fv /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils-0.17.0.dist-info/RECORD removed '/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils-0.17.0.dist-info/RECORD' + rm -fv /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils-0.17.0.dist-info/REQUESTED removed '/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils-0.17.0.dist-info/REQUESTED' + '[' -f /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-dep-overrides ']' ++ wc -l /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-ghost-distinfo ++ cut -f1 '-d ' + lines=1 + '[' 1 -ne 1 ']' + RPM_FILES_ESCAPE=4.19 + /usr/bin/python3 /usr/lib/rpm/redhat/pyproject_save_files.py --output-files /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-files --output-modules /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-modules --buildroot /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT --sitelib /usr/lib/python3.14/site-packages --sitearch /usr/lib64/python3.14/site-packages --python-version 3.14 --pyproject-record /builddir/build/BUILD/python-sbmlutils-0.17.0-build/python-sbmlutils-0.17.0-1.fc44.aarch64-pyproject-record --prefix /usr -l sbmlutils + /usr/lib/rpm/check-buildroot + /usr/lib/rpm/redhat/brp-ldconfig + COMPRESS='gzip -9 -n' + COMPRESS_EXT=.gz + /usr/lib/rpm/brp-compress + /usr/lib/rpm/brp-strip /usr/bin/strip + /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump + /usr/lib/rpm/redhat/brp-strip-lto /usr/bin/strip + /usr/lib/rpm/check-rpaths + /usr/lib/rpm/redhat/brp-mangle-shebangs *** WARNING: ./usr/lib/python3.14/site-packages/sbmlutils/resources/xslt/pmml2tex/run is executable but has no shebang, removing executable bit *** WARNING: ./usr/lib/python3.14/site-packages/sbmlutils/resources/xslt/pmml2tex/pmml2texfrag.xsl is executable but has no shebang, removing executable bit *** WARNING: ./usr/lib/python3.14/site-packages/sbmlutils/resources/xslt/pmml2tex/pmml2tex.xsl is executable but has no shebang, removing executable bit *** WARNING: ./usr/lib/python3.14/site-packages/sbmlutils/resources/xslt/pmml2tex/pmml-new.sty is executable but has no shebang, removing executable bit *** WARNING: ./usr/lib/python3.14/site-packages/sbmlutils/resources/xslt/pmml2tex/mml2tex.xsl is executable but has no shebang, removing executable bit *** WARNING: ./usr/lib/python3.14/site-packages/sbmlutils/resources/xslt/pmml2tex/csscolor.sty is executable but has no shebang, removing executable bit + /usr/lib/rpm/brp-remove-la-files + /usr/lib/rpm/redhat/brp-python-rpm-in-distinfo + env /usr/lib/rpm/redhat/brp-python-bytecompile '' 1 0 -j4 Bytecompiling .py files below /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14 using python3.14 + /usr/lib/rpm/redhat/brp-python-hardlink + /usr/bin/add-det --brp -j4 /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/utils.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/notes.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/log.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/cytoscape.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/console.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/biomodels.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/_antimony.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/parser.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/validation.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/__pycache__/reaction_equation.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/resources/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/report/__pycache__/units.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/report/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/__pycache__/miriam.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/report/__pycache__/sbmlreport.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/__pycache__/validator.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/manipulation/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/report/__pycache__/mathml.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/manipulation/__pycache__/merge.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/layout/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/__pycache__/annotator.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/io/__pycache__/sbml.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/layout/__pycache__/layout.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/io/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/io/__pycache__/antimony.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/fbc/__pycache__/fbc.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/fbc/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/fbc/__pycache__/cobra.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/io/__pycache__/files.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/report/__pycache__/sbmlinfo.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/__pycache__/fbc.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/__pycache__/comp.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/__pycache__/model.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/__pycache__/distrib.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/distrib/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/__pycache__/units.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/data/__pycache__/interpolation.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/data/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/converters/__pycache__/xpp_helpers.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/data/__pycache__/_driving.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/converters/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/converters/__pycache__/copasi.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/converters/__pycache__/xpp.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/converters/ode/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/__pycache__/_core.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/comp/__pycache__/flatten.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/comp/__pycache__/__init__.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/comp/__pycache__/comp.cpython-314.opt-1.pyc: rewriting with normalized contents /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/__pycache__/core_elements.cpython-314.opt-1.pyc: rewriting with normalized contents Scanned 63 directories and 381 files, processed 61 inodes, 52 modified (0 replaced + 52 rewritten), 0 unsupported format, 0 errors + /usr/bin/linkdupes --brp /builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr Scanned 62 directories and 381 files, considered 381 files, read 108 files, linked 7 files, 0 errors sum of sizes of linked files: 49769 bytes Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.u9hcyM + umask 022 + cd /builddir/build/BUILD/python-sbmlutils-0.17.0-build + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -I/usr/lib64/gfortran/modules ' + export FCFLAGS + VALAFLAGS=-g + export VALAFLAGS + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd sbmlutils-0.17.0 + /usr/bin/python3 -c 'import libsbml, sys; sys.exit(0 if hasattr(libsbml, "DISTRIB_UNCERTTYPE_COEFFIENTOFVARIATION") else 1)' + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -mbranch-protection=standard -fasynchronous-unwind-tables -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + PATH=/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin + PYTHONPATH=/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib64/python3.14/site-packages:/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages + PYTHONDONTWRITEBYTECODE=1 + PYTEST_ADDOPTS=' --ignore=/builddir/build/BUILD/python-sbmlutils-0.17.0-build/.pyproject-builddir' + PYTEST_XDIST_AUTO_NUM_WORKERS=4 + /usr/bin/pytest -q -m 'not sbml_testsuite' --ignore=tests/test_roundtrip.py --deselect tests/interpolation/test_interpolation_docs.py::test_guide_code_blocks_run --deselect tests/test_factory_facade.py::test_api_reference_lists_the_classes_and_functions ....................................FFFFFFFF..F.FF.F....F.F...F...F..... [ 4%] ...sssss................................................................ [ 9%] ........................................................................ [ 14%] ..............................................FF........................ [ 18%] ....F..FFFFFFFFFFFFFFFF.FFFF............................................ [ 23%] ...............................................................sssss.... [ 28%] ...................s.................................................... [ 32%] .......................................F..............F..EEEEEEEEEE..... [ 37%] ........................................................................ [ 42%] ........................................................................ [ 47%] ................................FF...................................... [ 51%] ........................................F............................... [ 56%] ........................................................................ [ 61%] ........................................................................ [ 65%] ....................................................s...............ssss [ 70%] s...........ssssssss.......ssssssss......ssssssss......ssFFssFFFF...F... [ 75%] s.....FF......F............................FFFFFFFFFFFFFFFFFFFFFFFFFFFFF [ 79%] FFFFFFFFFFFFFFFFFFFF.................................................FF. [ 84%] .F.......FsFFssssss.......sss.F..FFssFFF................ssFsssssssFFFsss [ 89%] ssss...........s........................................................ [ 94%] ........................................................................ [ 98%] ................... [100%] ==================================== ERRORS ==================================== ___ ERROR at setup of test_uncert_child_writes_meta_id_and_sbo_term[up_mean] ___ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) __ ERROR at setup of test_uncert_child_writes_meta_id_and_sbo_term[up_range] ___ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _______ ERROR at setup of test_uncert_child_writes_id_and_name[up_mean] ________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _______ ERROR at setup of test_uncert_child_writes_id_and_name[up_range] _______ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) __________ ERROR at setup of test_uncert_child_writes_notes[up_mean] ___________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) __________ ERROR at setup of test_uncert_child_writes_notes[up_range] __________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _______ ERROR at setup of test_uncert_child_writes_annotations[up_mean] ________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _______ ERROR at setup of test_uncert_child_writes_annotations[up_range] _______ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _____ ERROR at setup of test_uncert_child_writes_key_value_pairs[up_mean] ______ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _____ ERROR at setup of test_uncert_child_writes_key_value_pairs[up_range] _____ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: @pytest.fixture def uncert_metadata_doc() -> libsbml.SBMLDocument: """Write an uncertainty whose children carry every metadata field. The model is serialized and read back, so that the assertions are made on a document which went through the SBML writer and parser, not on the objects the factory created. Returns: the document read back from the written SBML; the test has to hold it, libsbml objects do not keep their document alive """ model = Model( "uncert_metadata", packages=[Package.DISTRIB_V1, Package.FBC_V3], parameters=[ Parameter( "p1", value=1.0, uncertainties=[ Uncertainty( "u1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0, sid="up_mean", name="mean of p1", metaId="meta_up_mean", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="mean of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=1.0, valueUpper=9.0, sid="up_range", name="range of p1", metaId="meta_up_range", sboTerm=UNCERT_SBO, annotations=[(BQB.IS, "chebi/CHEBI:15377")], notes="range of the measurements", keyValuePairs=[ KeyValuePair( key="source", value="sabiork", uri="https://example.org/kvp", ) ], ) ], ) ], ) ], ) > doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_distrib.py:644: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:802: in create_sbml child.create_sbml(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:523: in create_sbml self._set_fields(span, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:534: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:210: in _set_fields super()._set_fields(sbase, None) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log setup ------------------------------ WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(u1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(u1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(u1, UncertSpan(15, 1.0 - 9.0 [None]), UncertParameter(4, 5.0 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) =================================== FAILURES =================================== _________________ test_example_script[examples.converters.xpp] _________________ module = 'examples.converters.xpp' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_example_script_examples_c0') @pytest.mark.parametrize("module", SCRIPTS) def test_example_script(module: str, tmp_path: Path) -> None: """Every example runs without an error and writes into the working directory.""" if module in { "examples.converters.xpp", "examples.interpolation.driving", "examples.interpolation.interpolation", "examples.interpolation.pancreas", "examples.tiny.simulation", }: pytest.importorskip("roadrunner") env = dict(os.environ, PYTHONPATH=str(REPO_DIR), MPLBACKEND="Agg") result = subprocess.run( [sys.executable, "-m", module], cwd=tmp_path, env=env, capture_output=True, text=True, check=False, ) > assert result.returncode == 0, result.stderr E AssertionError: Traceback (most recent call last): E File "", line 203, in _run_module_as_main E File "", line 88, in _run_code E File "/builddir/build/BUILD/python-sbmlutils-0.17.0-build/sbmlutils-0.17.0/examples/converters/xpp.py", line 24, in E from sbmlutils.converters import xpp E ModuleNotFoundError: No module named 'sbmlutils' E E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3', '-m', 'examples.converters.xpp'], returncode=1, stdout='', stderr='Tracebac... line 24, in \n from sbmlutils.converters import xpp\nModuleNotFoundError: No module named \'sbmlutils\'\n').returncode tests/examples/test_example_scripts.py:55: AssertionError _______ test_example_script[examples.distrib.distrib_packages_examples] ________ module = 'examples.distrib.distrib_packages_examples' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_example_script_examples_d0') @pytest.mark.parametrize("module", SCRIPTS) def test_example_script(module: str, tmp_path: Path) -> None: """Every example runs without an error and writes into the working directory.""" if module in { "examples.converters.xpp", "examples.interpolation.driving", "examples.interpolation.interpolation", "examples.interpolation.pancreas", "examples.tiny.simulation", }: pytest.importorskip("roadrunner") env = dict(os.environ, PYTHONPATH=str(REPO_DIR), MPLBACKEND="Agg") result = subprocess.run( [sys.executable, "-m", module], cwd=tmp_path, env=env, capture_output=True, text=True, check=False, ) > assert result.returncode == 0, result.stderr E AssertionError: Traceback (most recent call last): E File "", line 203, in _run_module_as_main E File "", line 88, in _run_code E File "/builddir/build/BUILD/python-sbmlutils-0.17.0-build/sbmlutils-0.17.0/examples/distrib/distrib_packages_examples.py", line 18, in E from sbmlutils import validation E ModuleNotFoundError: No module named 'sbmlutils' E E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3', '-m', 'examples.distrib.distrib_packages_examples'], returncode=1, stdout='...py", line 18, in \n from sbmlutils import validation\nModuleNotFoundError: No module named \'sbmlutils\'\n').returncode tests/examples/test_example_scripts.py:55: AssertionError __________ test_example_script[examples.distrib.distrib_uncertainty] ___________ module = 'examples.distrib.distrib_uncertainty' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_example_script_examples_d1') @pytest.mark.parametrize("module", SCRIPTS) def test_example_script(module: str, tmp_path: Path) -> None: """Every example runs without an error and writes into the working directory.""" if module in { "examples.converters.xpp", "examples.interpolation.driving", "examples.interpolation.interpolation", "examples.interpolation.pancreas", "examples.tiny.simulation", }: pytest.importorskip("roadrunner") env = dict(os.environ, PYTHONPATH=str(REPO_DIR), MPLBACKEND="Agg") result = subprocess.run( [sys.executable, "-m", module], cwd=tmp_path, env=env, capture_output=True, text=True, check=False, ) > assert result.returncode == 0, result.stderr E AssertionError: Traceback (most recent call last): E File "", line 203, in _run_module_as_main E File "", line 88, in _run_code E File "/builddir/build/BUILD/python-sbmlutils-0.17.0-build/sbmlutils-0.17.0/examples/distrib/distrib_uncertainty.py", line 19, in E from sbmlutils import RESOURCES_DIR E ModuleNotFoundError: No module named 'sbmlutils' E E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3', '-m', 'examples.distrib.distrib_uncertainty'], returncode=1, stdout='', std..., line 19, in \n from sbmlutils import RESOURCES_DIR\nModuleNotFoundError: No module named \'sbmlutils\'\n').returncode tests/examples/test_example_scripts.py:55: AssertionError _____________ test_example_script[examples.interpolation.driving] ______________ module = 'examples.interpolation.driving' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_example_script_examples_i0') @pytest.mark.parametrize("module", SCRIPTS) def test_example_script(module: str, tmp_path: Path) -> None: """Every example runs without an error and writes into the working directory.""" if module in { "examples.converters.xpp", "examples.interpolation.driving", "examples.interpolation.interpolation", "examples.interpolation.pancreas", "examples.tiny.simulation", }: pytest.importorskip("roadrunner") env = dict(os.environ, PYTHONPATH=str(REPO_DIR), MPLBACKEND="Agg") result = subprocess.run( [sys.executable, "-m", module], cwd=tmp_path, env=env, capture_output=True, text=True, check=False, ) > assert result.returncode == 0, result.stderr E AssertionError: Traceback (most recent call last): E File "", line 203, in _run_module_as_main E File "", line 88, in _run_code E File "/builddir/build/BUILD/python-sbmlutils-0.17.0-build/sbmlutils-0.17.0/examples/interpolation/driving.py", line 25, in E from sbmlutils.comp import flatten_sbml E ModuleNotFoundError: No module named 'sbmlutils' E E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3', '-m', 'examples.interpolation.driving'], returncode=1, stdout='', stderr='T...ne 25, in \n from sbmlutils.comp import flatten_sbml\nModuleNotFoundError: No module named \'sbmlutils\'\n').returncode tests/examples/test_example_scripts.py:55: AssertionError __________ test_example_script[examples.interpolation.interpolation] ___________ module = 'examples.interpolation.interpolation' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_example_script_examples_i1') @pytest.mark.parametrize("module", SCRIPTS) def test_example_script(module: str, tmp_path: Path) -> None: """Every example runs without an error and writes into the working directory.""" if module in { "examples.converters.xpp", "examples.interpolation.driving", "examples.interpolation.interpolation", "examples.interpolation.pancreas", "examples.tiny.simulation", }: pytest.importorskip("roadrunner") env = dict(os.environ, PYTHONPATH=str(REPO_DIR), MPLBACKEND="Agg") result = subprocess.run( [sys.executable, "-m", module], cwd=tmp_path, env=env, capture_output=True, text=True, check=False, ) > assert result.returncode == 0, result.stderr E AssertionError: Traceback (most recent call last): E File "", line 203, in _run_module_as_main E File "", line 88, in _run_code E File "/builddir/build/BUILD/python-sbmlutils-0.17.0-build/sbmlutils-0.17.0/examples/interpolation/interpolation.py", line 26, in E from sbmlutils.data import interpolation as ip E ModuleNotFoundError: No module named 'sbmlutils' E E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3', '-m', 'examples.interpolation.interpolation'], returncode=1, stdout='', std...in \n from sbmlutils.data import interpolation as ip\nModuleNotFoundError: No module named \'sbmlutils\'\n').returncode tests/examples/test_example_scripts.py:55: AssertionError _____________ test_example_script[examples.interpolation.pancreas] _____________ module = 'examples.interpolation.pancreas' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_example_script_examples_i2') @pytest.mark.parametrize("module", SCRIPTS) def test_example_script(module: str, tmp_path: Path) -> None: """Every example runs without an error and writes into the working directory.""" if module in { "examples.converters.xpp", "examples.interpolation.driving", "examples.interpolation.interpolation", "examples.interpolation.pancreas", "examples.tiny.simulation", }: pytest.importorskip("roadrunner") env = dict(os.environ, PYTHONPATH=str(REPO_DIR), MPLBACKEND="Agg") result = subprocess.run( [sys.executable, "-m", module], cwd=tmp_path, env=env, capture_output=True, text=True, check=False, ) > assert result.returncode == 0, result.stderr E AssertionError: Traceback (most recent call last): E File "", line 203, in _run_module_as_main E File "", line 88, in _run_code E File "/builddir/build/BUILD/python-sbmlutils-0.17.0-build/sbmlutils-0.17.0/examples/interpolation/pancreas.py", line 29, in E from sbmlutils.console import console E ModuleNotFoundError: No module named 'sbmlutils' E E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3', '-m', 'examples.interpolation.pancreas'], returncode=1, stdout='', stderr='...line 29, in \n from sbmlutils.console import console\nModuleNotFoundError: No module named \'sbmlutils\'\n').returncode tests/examples/test_example_scripts.py:55: AssertionError ___________ test_example_script[examples.merge_models.merge_models] ____________ module = 'examples.merge_models.merge_models' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_example_script_examples_m0') @pytest.mark.parametrize("module", SCRIPTS) def test_example_script(module: str, tmp_path: Path) -> None: """Every example runs without an error and writes into the working directory.""" if module in { "examples.converters.xpp", "examples.interpolation.driving", "examples.interpolation.interpolation", "examples.interpolation.pancreas", "examples.tiny.simulation", }: pytest.importorskip("roadrunner") env = dict(os.environ, PYTHONPATH=str(REPO_DIR), MPLBACKEND="Agg") result = subprocess.run( [sys.executable, "-m", module], cwd=tmp_path, env=env, capture_output=True, text=True, check=False, ) > assert result.returncode == 0, result.stderr E AssertionError: Traceback (most recent call last): E File "", line 203, in _run_module_as_main E File "", line 88, in _run_code E File "/builddir/build/BUILD/python-sbmlutils-0.17.0-build/sbmlutils-0.17.0/examples/merge_models/merge_models.py", line 17, in E from sbmlutils.console import console E ModuleNotFoundError: No module named 'sbmlutils' E E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3', '-m', 'examples.merge_models.merge_models'], returncode=1, stdout='', stder...line 17, in \n from sbmlutils.console import console\nModuleNotFoundError: No module named \'sbmlutils\'\n').returncode tests/examples/test_example_scripts.py:55: AssertionError ________________ test_example_script[examples.tiny.simulation] _________________ module = 'examples.tiny.simulation' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_example_script_examples_t0') @pytest.mark.parametrize("module", SCRIPTS) def test_example_script(module: str, tmp_path: Path) -> None: """Every example runs without an error and writes into the working directory.""" if module in { "examples.converters.xpp", "examples.interpolation.driving", "examples.interpolation.interpolation", "examples.interpolation.pancreas", "examples.tiny.simulation", }: pytest.importorskip("roadrunner") env = dict(os.environ, PYTHONPATH=str(REPO_DIR), MPLBACKEND="Agg") result = subprocess.run( [sys.executable, "-m", module], cwd=tmp_path, env=env, capture_output=True, text=True, check=False, ) > assert result.returncode == 0, result.stderr E AssertionError: Traceback (most recent call last): E File "", line 203, in _run_module_as_main E File "", line 88, in _run_code E File "/builddir/build/BUILD/python-sbmlutils-0.17.0-build/sbmlutils-0.17.0/examples/tiny/simulation.py", line 28, in E from examples.tiny import tiny E File "/builddir/build/BUILD/python-sbmlutils-0.17.0-build/sbmlutils-0.17.0/examples/tiny/tiny.py", line 6, in E import sbmlutils.layout as layout E ModuleNotFoundError: No module named 'sbmlutils' E E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3', '-m', 'examples.tiny.simulation'], returncode=1, stdout='', stderr='Traceba...py", line 6, in \n import sbmlutils.layout as layout\nModuleNotFoundError: No module named \'sbmlutils\'\n').returncode tests/examples/test_example_scripts.py:55: AssertionError _______ test_create_example_create[examples.tutorial.model_composition] ________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_example_create_exa2') module = @pytest.mark.parametrize("module", examples_create) def test_create_example_create(tmp_path: Path, module: Any) -> None: """Test that an example writes models and that every one of them is valid.""" > module.create(output_dir=tmp_path) tests/examples/test_examples.py:19: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ examples/tutorial/model_composition.py:26: in create return create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ________________ test_create_example_create[examples.demo.demo] ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_example_create_exa4') module = @pytest.mark.parametrize("module", examples_create) def test_create_example_create(tmp_path: Path, module: Any) -> None: """Test that an example writes models and that every one of them is valid.""" > module.create(output_dir=tmp_path) tests/examples/test_examples.py:19: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ examples/demo/demo.py:213: in create create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1773: in create_model doc = annotator.annotate_sbml_doc( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:276: in annotate_sbml_doc annotator.annotate_model() ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:429: in annotate_model self._annotate_elements(elements, a) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:523: in _annotate_elements annotation = Annotation( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(scale_f, metabolic scaling factor)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Vmax_bA)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Vmax_bA)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Km_A)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Km_A)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Vmax_bB)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Vmax_bB)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Km_B)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Km_B)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Vmax_bC)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Vmax_bC)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Km_C)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Km_C)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Vmax_v1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Vmax_v1)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Keq_v1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Keq_v1)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Vmax_v2)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Vmax_v2)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Vmax_v3)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Vmax_v3)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Vmax_v4)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Vmax_v4)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(Keq_v4)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Keq_v4)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(e, external compartment)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c, cell compartment)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(m, plasma membrane)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(c__A, A)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(c__B, B)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(c__C, C)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(e__A, A)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(e__B, B)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(e__C, C)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Reaction(bA, bA (A import))' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Reaction(bB, bB (B export))' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Reaction(bC, bC (C export))' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Reaction(v1, v1 (A -> B))' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Reaction(v2, v2 (A -> C))' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Reaction(v3, v3 (C -> A))' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Reaction(v4, v4 (C -> B))' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ________________ test_create_example_create[examples.tiny.tiny] ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_example_create_exa5') module = @pytest.mark.parametrize("module", examples_create) def test_create_example_create(tmp_path: Path, module: Any) -> None: """Test that an example writes models and that every one of them is valid.""" > module.create(output_dir=tmp_path) tests/examples/test_examples.py:19: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ examples/tiny/tiny.py:434: in create return create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1773: in create_model doc = annotator.annotate_sbml_doc( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:276: in annotate_sbml_doc annotator.annotate_model() ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:429: in annotate_model self._annotate_elements(elements, a) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:523: in _annotate_elements annotation = Annotation( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Function(f_oscillation)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Function(f_oscillation)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(minus_1000, SBO_0000625)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(plus_1000, SBO_0000625)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c, cell compartment, True)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'InitialAssignment()' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'InitialAssignment()' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(a_sum, ATP + ADP balance)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Event(event_1, reset concentrations)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Constraint(constraint_1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Constraint(constraint_1)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Objective(atp_consume_max)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Objective(atp_consume_max)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'FluxObjective()' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'FluxObjective()' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Layout(layout_1, Layout 1)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'SpeciesGlyph(glyph_atp)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'SpeciesGlyph(glyph_atp)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'SpeciesGlyph(glyph_adp)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'SpeciesGlyph(glyph_adp)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'SpeciesGlyph(glyph_glc)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'SpeciesGlyph(glyph_glc)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'SpeciesGlyph(glyph_g6p)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'SpeciesGlyph(glyph_g6p)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'SpeciesGlyph(glyph_hydron)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'SpeciesGlyph(glyph_hydron)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'ReactionGlyph(glyph_GK)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'ReactionGlyph(glyph_GK)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'ReactionGlyph(glyph_ATPPROD)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'ReactionGlyph(glyph_ATPPROD)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING sbmlutils.factory._core:_core.py:250 The 'name' of 1 element(s) is not written: SBML L3V1 has no such attribute, e.g. 'AssignmentRule(ATP + ADP balance)'. Write SBML Level 3 Version 2 to keep it. WARNING sbmlutils.factory._core:_core.py:250 The 'id' of 1 element(s) is not written: SBML L3V1 has no such attribute, e.g. 'Constraint(constraint_1)'. Write SBML Level 3 Version 2 to keep it. _______________ test_create_example_models[examples.annotation] ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_example_models_exa1') module = @pytest.mark.parametrize("module", examples_models) def test_create_example_models(tmp_path: Path, module: Any) -> None: """Test create model.""" model_path: Path = tmp_path / "model.xml" > results = create_model( model=module.model, filepath=model_path, ) tests/examples/test_examples.py:35: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:314: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:340: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(x_cell, cell diameter)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Vol_e, external volume)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(A_m, membrane area)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Compartment(ext, external, SBO_0000290)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _______________ test_create_example_models[examples.fbc.fbc_v2] ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_example_models_exa6') module = @pytest.mark.parametrize("module", examples_models) def test_create_example_models(tmp_path: Path, module: Any) -> None: """Test create model.""" model_path: Path = tmp_path / "model.xml" > results = create_model( model=module.model, filepath=model_path, ) tests/examples/test_examples.py:35: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/fbc.py:145: in create_sbml self._set_fields(gene_product, model=model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(bioreactor, bioreactor)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(Glcxt, glucose)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(Ac, acetate)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(O2, oxygen)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(X, biomass)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s_Rv0649, s_Rv0649 (GeneProduct))' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'GeneProduct(gene1, meta_gene_1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'GeneProduct(gene1, meta_gene_1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'GeneProduct(gene1, meta_gene_1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ___________ test_create_example_models[examples.fbc.fbc_mass_charge] ___________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_example_models_exa8') module = @pytest.mark.parametrize("module", examples_models) def test_create_example_models(tmp_path: Path, module: Any) -> None: """Test create model.""" model_path: Path = tmp_path / "model.xml" > results = create_model( model=module.model, filepath=model_path, ) tests/examples/test_examples.py:35: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:314: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:340: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(HEX1_v)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(HEX1_v)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Compartment(cyto, cytosol, SBO_0000290)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) __________________ test_create_example_models[examples.model] __________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_example_models_exa12') module = @pytest.mark.parametrize("module", examples_models) def test_create_example_models(tmp_path: Path, module: Any) -> None: """Test create model.""" model_path: Path = tmp_path / "model.xml" > results = create_model( model=module.model, filepath=model_path, ) tests/examples/test_examples.py:35: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:314: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:340: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(k1, SBO_0000009)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(cell, SBO_0000290, meta_cell, [Uncertainty(UncertSpan(15, 0.2 - 3.0 [None]), UncertParameter(4, 1.0 [None]), UncertParameter(9, 0.1 [None]), UncertParameter(0, None [None]))])' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Compartment(cell, SBO_0000290, meta_cell, [Uncertainty(UncertSpan(15, 0.2 - 3.0 [None]), UncertParameter(4, 1.0 [None]), UncertParameter(9, 0.1 [None]), UncertParameter(0, None [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ________________ test_create_example_models[examples.parameter] ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_example_models_exa16') module = @pytest.mark.parametrize("module", examples_models) def test_create_example_models(tmp_path: Path, module: Any) -> None: """Test create model.""" model_path: Path = tmp_path / "model.xml" > results = create_model( model=module.model, filepath=model_path, ) tests/examples/test_examples.py:35: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p1)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p2)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p2)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p3)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p3)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p4)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p4)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(dose, SBO_0000002, meta_dose)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(dose, SBO_0000002, meta_dose)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ________ test_read_sbml_reads_a_file_without_an_xml_declaration[model] _________ tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_read_sbml_reads_a_file_wi1') content = '' @pytest.mark.parametrize( "content", [ pytest.param( _SBML_NO_DECLARATION.replace("/>", '>'), id="model", ), pytest.param( _SBML_COMP_LIBRARY.removeprefix(''), id="comp-library", ), ], ) def test_read_sbml_reads_a_file_without_an_xml_declaration( tmp_path: Path, content: str ) -> None: """A missing declaration is an error of the document, it was read in full. libsbml reports `MissingXMLEncoding` and `BadXMLDecl` for it, both of severity error; the document is kept with them for the validation. """ sbml_path = tmp_path / "model.xml" sbml_path.write_text(content, encoding="utf-8") doc = read_sbml(sbml_path) assert doc.getModel() is not None or ( doc.getPlugin("comp").getNumModelDefinitions() == 1 ) > assert libsbml.BadXMLDecl in {e[0] for e in _errors(doc)} E assert 1003 in {1002} E + where 1003 = libsbml.BadXMLDecl tests/io/test_sbml.py:575: AssertionError ------------------------------ Captured log call ------------------------------- ERROR sbmlutils.validation:validation.py:522 [black on white]ENone: XML content (core, L1, code)[/black on white] [error][on black][Error] Missing XML encoding attribute[/on black][/error] Missing encoding attribute in XML declaration. ERROR sbmlutils.io.sbml:sbml.py:75 `read_sbml`: errors encountered while reading the SBML file '/tmp/pytest-of-mockbuild/pytest-0/test_read_sbml_reads_a_file_wi1/model.xml'. _____ test_read_sbml_reads_a_file_without_an_xml_declaration[comp-library] _____ tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_read_sbml_reads_a_file_wi2') content = '' @pytest.mark.parametrize( "content", [ pytest.param( _SBML_NO_DECLARATION.replace("/>", '>'), id="model", ), pytest.param( _SBML_COMP_LIBRARY.removeprefix(''), id="comp-library", ), ], ) def test_read_sbml_reads_a_file_without_an_xml_declaration( tmp_path: Path, content: str ) -> None: """A missing declaration is an error of the document, it was read in full. libsbml reports `MissingXMLEncoding` and `BadXMLDecl` for it, both of severity error; the document is kept with them for the validation. """ sbml_path = tmp_path / "model.xml" sbml_path.write_text(content, encoding="utf-8") doc = read_sbml(sbml_path) assert doc.getModel() is not None or ( doc.getPlugin("comp").getNumModelDefinitions() == 1 ) > assert libsbml.BadXMLDecl in {e[0] for e in _errors(doc)} E assert 1003 in {1002} E + where 1003 = libsbml.BadXMLDecl tests/io/test_sbml.py:575: AssertionError ------------------------------ Captured log call ------------------------------- ERROR sbmlutils.validation:validation.py:522 [black on white]ENone: XML content (core, L1, code)[/black on white] [error][on black][Error] Missing XML encoding attribute[/on black][/error] Missing encoding attribute in XML declaration. ERROR sbmlutils.io.sbml:sbml.py:75 `read_sbml`: errors encountered while reading the SBML file '/tmp/pytest-of-mockbuild/pytest-0/test_read_sbml_reads_a_file_wi2/model.xml'. ____________________________ test_create_annotation ____________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_create_annotation0') def test_create_annotation(tmp_path: Path) -> None: """Create assignment model.""" model_path: Path = tmp_path / "model.xml" > create_model(annotation_example.model, filepath=model_path) tests/metadata/test_annotator.py:32: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:314: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:340: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(x_cell, cell diameter)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(Vol_e, external volume)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(A_m, membrane area)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Compartment(ext, external, SBO_0000290)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ____________________________ test_model_annotation _____________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_model_annotation0') def test_model_annotation(tmp_path: Path) -> None: """Create minimal model and check that annotation is written correctly.""" model_dict: ModelDict = { "sid": "example_annotation", "compartments": [ Compartment( sid="C", value=1.0, sboTerm=SBO.PHYSICAL_COMPARTMENT, annotations=[ (BQB.IS, "chebi/CHEBI:28061"), # alpha-D-galactose ], ) ], } > results = create_model( model=Model(**model_dict), filepath=tmp_path / "annotation1.xml" ) tests/metadata/test_annotator.py:83: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:314: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:340: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(C, SBO_0000290)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Compartment(C, SBO_0000290)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _____________________________ test_demo_annotation _____________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_demo_annotation0') def test_demo_annotation(tmp_path: Path) -> None: """Annotate the demo network.""" tmp_sbml_path = tmp_path / "sbml_annotated.xml" > annotator.annotate_sbml( DEMO_SBML_NO_ANNOTATIONS, DEMO_ANNOTATIONS, filepath=tmp_sbml_path ) tests/metadata/test_annotator.py:106: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:257: in annotate_sbml doc = annotate_sbml_doc(doc, external_annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:276: in annotate_sbml_doc annotator.annotate_model() ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:429: in annotate_model self._annotate_elements(elements, a) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:523: in _annotate_elements annotation = Annotation( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset __________________________ test_galactose_annotation ___________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_galactose_annotation0') def test_galactose_annotation(tmp_path: Path) -> None: """Annotate the galactose network from the annotations of a spreadsheet.""" assert ( _annotated_elements(read_sbml(GALACTOSE_SINGLECELL_SBML_NO_ANNOTATIONS)) == [] ) tmp_sbml_path = tmp_path / "sbml_annotated.xml" > annotator.annotate_sbml( GALACTOSE_SINGLECELL_SBML_NO_ANNOTATIONS, annotations_path=GALACTOSE_ANNOTATIONS, filepath=tmp_sbml_path, ) tests/metadata/test_annotator.py:219: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:257: in annotate_sbml doc = annotate_sbml_doc(doc, external_annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:276: in annotate_sbml_doc annotator.annotate_model() ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:429: in annotate_model self._annotate_elements(elements, a) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/metadata/annotator.py:523: in _annotate_elements annotation = Annotation( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_annotation_resource_which_cannot_be_normalized_is_written_as_given[urn:miriam:sbmlutils.test.collection1] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:sbmlutils.test.collection1' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_which0') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff67c08490> @pytest.mark.parametrize("resource", LOSSY_RESOURCES) def test_annotation_resource_which_cannot_be_normalized_is_written_as_given( resource: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource is written as given rather than as something else. An annotation is written as `RDFAnnotation.resource_normalized`, which does not exist for a resource without a term and is not a resource of identifiers.org any more for one without a collection. Writing either would make the annotation say something else than the model definition did. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:350: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:302: in __init__ self.validate() /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:474: in validate valid_term = self.check_miriam_term() ^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:413: in check_miriam_term namespace: Namespace | None = get_registry().ns_dict.get( ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING pymetadata.core.annotation:annotation.py:295 Deprecated urn pattern `urn:miriam:sbmlutils.test.collection1` updated: None WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_which_cannot_be_normalized_is_written_as_given[urn:miriam:sbmlutils.test.collection1:] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:sbmlutils.test.collection1:' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_which1') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff67c087c0> @pytest.mark.parametrize("resource", LOSSY_RESOURCES) def test_annotation_resource_which_cannot_be_normalized_is_written_as_given( resource: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource is written as given rather than as something else. An annotation is written as `RDFAnnotation.resource_normalized`, which does not exist for a resource without a term and is not a resource of identifiers.org any more for one without a collection. Writing either would make the annotation say something else than the model definition did. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:350: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:302: in __init__ self.validate() /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:474: in validate valid_term = self.check_miriam_term() ^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:413: in check_miriam_term namespace: Namespace | None = get_registry().ns_dict.get( ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING pymetadata.core.annotation:annotation.py:295 Deprecated urn pattern `urn:miriam:sbmlutils.test.collection1:` updated: None WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_which_cannot_be_normalized_is_written_as_given[sbmlutils.test.collection1/] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'sbmlutils.test.collection1/' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_which2') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6ea09850> @pytest.mark.parametrize("resource", LOSSY_RESOURCES) def test_annotation_resource_which_cannot_be_normalized_is_written_as_given( resource: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource is written as given rather than as something else. An annotation is written as `RDFAnnotation.resource_normalized`, which does not exist for a resource without a term and is not a resource of identifiers.org any more for one without a collection. Writing either would make the annotation say something else than the model definition did. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:350: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:302: in __init__ self.validate() /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:474: in validate valid_term = self.check_miriam_term() ^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:413: in check_miriam_term namespace: Namespace | None = get_registry().ns_dict.get( ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_which_cannot_be_normalized_is_written_as_given[urn:miriam::bar] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam::bar' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_which3') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6e974b50> @pytest.mark.parametrize("resource", LOSSY_RESOURCES) def test_annotation_resource_which_cannot_be_normalized_is_written_as_given( resource: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource is written as given rather than as something else. An annotation is written as `RDFAnnotation.resource_normalized`, which does not exist for a resource without a term and is not a resource of identifiers.org any more for one without a collection. Writing either would make the annotation say something else than the model definition did. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:350: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:298: in __init__ self.resource_normalized, ^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:377: in resource_normalized namespace = get_registry().ns_dict.get(self.collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_of_a_known_collection_is_normalized[chebi/CHEBI:12965-https://identifiers.org/CHEBI:12965] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'chebi/CHEBI:12965', expected = 'https://identifiers.org/CHEBI:12965' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_of_a_0') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff67c96b70> @pytest.mark.parametrize(("resource", "expected"), NORMALIZED_RESOURCES) def test_annotation_resource_of_a_known_collection_is_normalized( resource: str, expected: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource which keeps its collection and term is normalized. Every one of these normalizes to an identifiers.org URL of the collection and term it was given with, so nothing is lost and no warning is due. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:406: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_of_a_known_collection_is_normalized[urn:miriam:chebi:CHEBI%3A33699-https://identifiers.org/CHEBI:33699] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:chebi:CHEBI%3A33699' expected = 'https://identifiers.org/CHEBI:33699' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_of_a_1') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff67c957c0> @pytest.mark.parametrize(("resource", "expected"), NORMALIZED_RESOURCES) def test_annotation_resource_of_a_known_collection_is_normalized( resource: str, expected: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource which keeps its collection and term is normalized. Every one of these normalizes to an identifiers.org URL of the collection and term it was given with, so nothing is lost and no warning is due. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:406: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_of_a_known_collection_is_normalized[http://identifiers.org/BTO:0000131-https://identifiers.org/BTO:0000131] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/BTO:0000131' expected = 'https://identifiers.org/BTO:0000131' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_of_a_2') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6e9b9550> @pytest.mark.parametrize(("resource", "expected"), NORMALIZED_RESOURCES) def test_annotation_resource_of_a_known_collection_is_normalized( resource: str, expected: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource which keeps its collection and term is normalized. Every one of these normalizes to an identifiers.org URL of the collection and term it was given with, so nothing is lost and no warning is due. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:406: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_of_a_known_collection_is_normalized[UO:0000021-https://identifiers.org/UO:0000021] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'UO:0000021', expected = 'https://identifiers.org/UO:0000021' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_of_a_3') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6e9b8750> @pytest.mark.parametrize(("resource", "expected"), NORMALIZED_RESOURCES) def test_annotation_resource_of_a_known_collection_is_normalized( resource: str, expected: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource which keeps its collection and term is normalized. Every one of these normalizes to an identifiers.org URL of the collection and term it was given with, so nothing is lost and no warning is due. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:406: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_of_a_known_collection_is_normalized[http://identifiers.org/sbmlutils.test.collection1/1406-https://identifiers.org/sbmlutils.test.collection1/1406] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/sbmlutils.test.collection1/1406' expected = 'https://identifiers.org/sbmlutils.test.collection1/1406' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_of_a_4') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6e5c1e60> @pytest.mark.parametrize(("resource", "expected"), NORMALIZED_RESOURCES) def test_annotation_resource_of_a_known_collection_is_normalized( resource: str, expected: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource which keeps its collection and term is normalized. Every one of these normalizes to an identifiers.org URL of the collection and term it was given with, so nothing is lost and no warning is due. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:406: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_of_a_known_collection_is_normalized[http://identifiers.org/sbmlutils.test.collection1/XX:0000040-https://identifiers.org/sbmlutils.test.collection1/XX:0000040] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/sbmlutils.test.collection1/XX:0000040' expected = 'https://identifiers.org/sbmlutils.test.collection1/XX:0000040' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_of_a_5') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6e91bdd0> @pytest.mark.parametrize(("resource", "expected"), NORMALIZED_RESOURCES) def test_annotation_resource_of_a_known_collection_is_normalized( resource: str, expected: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource which keeps its collection and term is normalized. Every one of these normalizes to an identifiers.org URL of the collection and term it was given with, so nothing is lost and no warning is due. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:406: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_of_a_known_collection_is_normalized[https://identifiers.org/SBMLUTILS.TEST.COLLECTION1:0000012-https://identifiers.org/SBMLUTILS.TEST.COLLECTION1:0000012] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'https://identifiers.org/SBMLUTILS.TEST.COLLECTION1:0000012' expected = 'https://identifiers.org/SBMLUTILS.TEST.COLLECTION1:0000012' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_of_a_6') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff76423110> @pytest.mark.parametrize(("resource", "expected"), NORMALIZED_RESOURCES) def test_annotation_resource_of_a_known_collection_is_normalized( resource: str, expected: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource which keeps its collection and term is normalized. Every one of these normalizes to an identifiers.org URL of the collection and term it was given with, so nothing is lost and no warning is due. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:406: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_of_a_known_collection_is_normalized[http://identifiers.org/chebi/000000035-https://identifiers.org/chebi/000000035] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/chebi/000000035' expected = 'https://identifiers.org/chebi/000000035' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_of_a_7') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6e95f5f0> @pytest.mark.parametrize(("resource", "expected"), NORMALIZED_RESOURCES) def test_annotation_resource_of_a_known_collection_is_normalized( resource: str, expected: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource which keeps its collection and term is normalized. Every one of these normalizes to an identifiers.org URL of the collection and term it was given with, so nothing is lost and no warning is due. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:406: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_annotation_resource_of_a_known_collection_is_normalized[urn:miriam:sbmlutils.test.collection1:bar-https://identifiers.org/sbmlutils.test.collection1/bar] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:sbmlutils.test.collection1:bar' expected = 'https://identifiers.org/sbmlutils.test.collection1/bar' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_resource_of_a_8') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6e95d440> @pytest.mark.parametrize(("resource", "expected"), NORMALIZED_RESOURCES) def test_annotation_resource_of_a_known_collection_is_normalized( resource: str, expected: str, tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource which keeps its collection and term is normalized. Every one of these normalizes to an identifiers.org URL of the collection and term it was given with, so nothing is lost and no warning is due. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_species(resource, sbml_path) tests/metadata/test_annotator.py:406: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:289: in _annotated_species _annotated_model([resource], sbml_path) tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ___________ test_annotation_losses_are_reported_once_per_collection ____________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_losses_are_rep0') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6e97ecb0> def test_annotation_losses_are_reported_once_per_collection( tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a document reports one warning per collection, not per resource. Writing one warning per resource buried every other message, 19853 of them for the Recon3D fixture while pymetadata up to 0.6.3 lost the collections the registry does not know, and taught users to silence the logger. The detail of each resource stays available at debug. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.DEBUG, logger="sbmlutils.metadata.annotator"): > _annotated_model(TWO_LOSSY_COLLECTIONS, sbml_path) tests/metadata/test_annotator.py:451: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:302: in __init__ self.validate() /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:474: in validate valid_term = self.check_miriam_term() ^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:413: in check_miriam_term namespace: Namespace | None = get_registry().ns_dict.get( ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING pymetadata.core.annotation:annotation.py:295 Deprecated urn pattern `urn:miriam:sbmlutils.test.collection1` updated: None WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _____________ test_annotation_losses_do_not_leak_between_documents _____________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_losses_do_not_0') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff67953800> def test_annotation_losses_do_not_leak_between_documents( tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that each written document reports its own resources. The collector is installed per document. A collector kept beyond the document it was installed for would add the resources of the first document to the report of the second. """ with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_model(TWO_LOSSY_COLLECTIONS[:3], tmp_path / "first.xml") tests/metadata/test_annotator.py:482: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:302: in __init__ self.validate() /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:474: in validate valid_term = self.check_miriam_term() ^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:413: in check_miriam_term namespace: Namespace | None = get_registry().ns_dict.get( ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING pymetadata.core.annotation:annotation.py:295 Deprecated urn pattern `urn:miriam:sbmlutils.test.collection1` updated: None WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _________ test_annotation_loss_without_a_collection_is_grouped_as_such _________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_annotation_loss_without_a0') caplog = <_pytest.logging.LogCaptureFixture object at 0xffff64c0a950> def test_annotation_loss_without_a_collection_is_grouped_as_such( tmp_path: Path, caplog: pytest.LogCaptureFixture ) -> None: """Test that a resource with an empty collection is still reported. There is no collection to group such a resource under, and dropping it from the report for that reason would hide it entirely, so all of them are reported together under a placeholder. """ sbml_path = tmp_path / "annotation.xml" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > _annotated_model(["urn:miriam::bar", "urn:miriam::baz"], sbml_path) tests/metadata/test_annotator.py:511: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/metadata/test_annotator.py:263: in _annotated_model create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:298: in __init__ self.resource_normalized, ^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:377: in resource_normalized namespace = get_registry().ns_dict.get(self.collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _______ test_annotation_loss_outside_a_document_is_reported_per_resource _______ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: caplog = <_pytest.logging.LogCaptureFixture object at 0xffff6766ced0> def test_annotation_loss_outside_a_document_is_reported_per_resource( caplog: pytest.LogCaptureFixture, ) -> None: """Test that a single annotation written on its own reports itself. `ModelAnnotator.annotate_sbase` annotates one element at a time and is called directly. There is no document scope then, and nothing would ever report a resource which was only collected. """ doc = libsbml.SBMLDocument(3, 2) model: libsbml.Model = doc.createModel("m") compartment: libsbml.Compartment = model.createCompartment() compartment.setId("c") compartment.setConstant(True) resource = f"urn:miriam:{UNKNOWN_COLLECTION}" with caplog.at_level(logging.WARNING, logger="sbmlutils.metadata.annotator"): > ModelAnnotator.annotate_sbase(compartment, Annotation(BQB.IS, resource)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/metadata/test_annotator.py:536: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:302: in __init__ self.validate() /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:474: in validate valid_term = self.check_miriam_term() ^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:413: in check_miriam_term namespace: Namespace | None = get_registry().ns_dict.get( ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING pymetadata.core.annotation:annotation.py:295 Deprecated urn pattern `urn:miriam:sbmlutils.test.collection1` updated: None WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset __________________ test_retained_annotation_is_informational ___________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_retained_annotation_is_in0') def test_retained_annotation_is_informational(tmp_path: Path) -> None: """Strict construction accepts resources which are preserved verbatim.""" from sbmlutils.factory import Compartment, Species from sbmlutils.metadata import BQB resource = "urn:miriam::bar" model = Model( "m", compartments=[Compartment("c", 1)], species=[Species("s", "c", initialAmount=1, annotations=[(BQB.IS, resource)])], ) > result = create_model(model, tmp_path / "m.xml", strict=True, validate=False) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_construction_diagnostics.py:165: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:298: in __init__ self.resource_normalized, ^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:377: in resource_normalized namespace = get_registry().ns_dict.get(self.collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Compartment(c)' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Species(s)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Species(s)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(s)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ___________________________ test_sabiork_uncertainty ___________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: def test_sabiork_uncertainty() -> None: """Test SabioRK uncertainty.""" model_dict: dict[str, Any] = { "sid": "sabiork_parameter", "packages": [Package.DISTRIB_V1], "model_units": ModelUnits( time=U.hr, extent=U.mole, substance=U.mole, length=U.meter, area=U.m2, volume=U.liter, ), "units": U, "parameters": [ Parameter( sid="Km_glc", name="Michelis-Menten constant glucose", value=5.0, unit=U.mM, sboTerm=SBO.MICHAELIS_CONSTANT, uncertainties=[ Uncertainty( sid="uncertainty1", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.07 ), UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_STANDARDDEVIATION, value=0.97, ), ], annotations=[ (BQB.IS, "sabiork.kineticrecord/793"), # entry in SABIO-RK (BQB.HAS_TAXON, "taxonomy/9606"), # homo sapiens (BQB.IS, "ec-code/2.7.1.2"), # glucokinase (BQB.IS, "uniprot/P35557"), # Glucokinase homo sapiens (BQB.IS, "bto/BTO:0000075"), # liver ], ), Uncertainty( sid="uncertainty2", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=2.7 ), UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_STANDARDDEVIATION, value=0.11, ), ], annotations=[ (BQB.IS, "sabiork.kineticrecord/2581"), # entry in SABIO-RK (BQB.HAS_TAXON, "taxonomy/9606"), # homo sapiens (BQB.IS, "ec-code/2.7.1.2"), # glucokinase (BQB.IS, "uniprot/P35557"), # Glucokinase homo sapiens (BQB.IS, "bto/BTO:0000075"), # liver ], ), ], ) ], } > check_model(Model(**model_dict)) tests/test_distrib.py:511: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_distrib.py:88: in check_model doc: libsbml.SBMLDocument = Document(model=model).create_sbml() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:797: in create_sbml self._set_fields(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Uncertainty(uncertainty1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Uncertainty(uncertainty1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(Km_glc, Michelis-Menten constant glucose, SBO_0000027, [Uncertainty(uncertainty1, UncertParameter(4, 5.07 [None]), UncertParameter(9, 0.97 [None])), Uncertainty(uncertainty2, UncertParameter(4, 2.7 [None]), UncertParameter(9, 0.11 [None]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) __________________ test_reaction_modifier_keeps_sbase_fields ___________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: def test_reaction_modifier_keeps_sbase_fields() -> None: """Test that a modifier's metaId, sboTerm, name, notes and annotation survive. The writer of a species reference used to only set `species`, `sid`, `constant`, `stoichiometry`, `metaId` and `sboTerm`; `name`, `notes` and `annotations` were silently dropped, for reactants, products and modifiers alike. This asserts against the actual created `libsbml.ModifierSpeciesReference`, not against the python `EquationPart` it was built from, so it fails if `_SpeciesReference` stops writing any of these. """ _doc, model = _reaction_test_model() equation = ReactionEquation( reactants=[EquationPart(species="A")], products=[EquationPart(species="B")], modifiers=[ EquationPart( species="M", metaId="mod1", sboTerm="SBO:0000019", name="modifiername", notes="a modifier", annotations=[(BQB.IS, "uniprot/P35557")], ) ], ) reaction = Reaction("r1", equation) > reaction.create_sbml(model) tests/test_factory.py:1633: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:1440: in create_sbml _SpeciesReference(modifier)._set_fields(r.createModifier(), model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:1256: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Reaction(r1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Reaction(r1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ___________ test_reaction_reactant_keeps_name_notes_and_annotations ____________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: def test_reaction_reactant_keeps_name_notes_and_annotations() -> None: """Test that a reactant's name, notes and annotation survive, not only its metadata. Only `metaId`/`sboTerm`/`constant`/`stoichiometry` were set on a `SpeciesReference` before this task; `name`, `notes` and `annotations` were dropped for reactants and products exactly like for modifiers. """ _doc, model = _reaction_test_model() equation = ReactionEquation( reactants=[ EquationPart( species="A", name="reactantname", notes="a reactant", annotations=[(BQB.IS, "uniprot/P35557")], ) ], products=[EquationPart(species="B")], ) reaction = Reaction("r1", equation) > reaction.create_sbml(model) tests/test_factory.py:1664: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:1434: in create_sbml _SpeciesReference(reactant)._set_fields(r.createReactant(), model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:1256: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Reaction(r1)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Reaction(r1)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_an_annotation_which_is_neither_an_annotation_nor_a_tuple_raises[second] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_an_annotation_which_is_ne1') annotations = [(, 'chebi/CHEBI:15422'), 'chebi/CHEBI:15422'] @pytest.mark.parametrize( "annotations", [ pytest.param(["chebi/CHEBI:15422"], id="first"), pytest.param([(BQB.IS, "chebi/CHEBI:15422"), "chebi/CHEBI:15422"], id="second"), ], ) def test_an_annotation_which_is_neither_an_annotation_nor_a_tuple_raises( tmp_path: Path, annotations: list[Any] ) -> None: """An annotation entry of an unsupported type raises instead of failing late. As the first entry it raised an `UnboundLocalError`, after another entry it silently duplicated the annotation before it. """ model = Model( "m", parameters=[Parameter("p", 1.0, annotations=annotations)], ) with pytest.raises(ValueError, match="chebi/CHEBI:15422"): > create_model(model, filepath=tmp_path / "model.xml", validate=False) tests/test_factory.py:3564: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(p)' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(p)' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ________________ test_roundtrip_document_returns_both_documents ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_roundtrip_document_return0') def test_roundtrip_document_returns_both_documents(tmp_path: Path) -> None: """Test that a round trip returns the document read and the one written.""" > doc_in, doc_out = roundtrip_document(UNCERTAINTY_SBML, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:953: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:797: in create_sbml self._set_fields(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(UncertParameter(4, 5.0 [mole]), UncertParameter(9, 0.3 [mole]), UncertSpan(15, 2.0 - 8.0 [mole])), Uncertainty(UncertParameter(2, 0.0 [mole]), UncertParameter(3, 1.0 [mole]), UncertParameter(4, 2.0 [mole]), UncertParameter(5, 3.0 [mole]), UncertParameter(6, 4.0 [mole]), UncertParameter(7, 5.0 [mole]), UncertParameter(8, 6.0 [mole]), UncertParameter(9, 7.0 [mole]), UncertParameter(10, 8.0 [mole]), UncertParameter(11, 9.0 [mole])), Uncertainty(UncertSpan(12, -1.0 - 1.0 [mole]), UncertSpan(13, 0.0 - 2.0 [mole]), UncertSpan(14, 1.0 - 3.0 [mole]), UncertSpan(15, 2.0 - 4.0 [mole])), Uncertainty(UncertParameter(0, None [None])), Uncertainty(UncertParameter(1, 0.25 [mole])), Uncertainty(UncertParameter(0, None [mole]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _____________________ test_roundtrip_preserves_fbc_strict ______________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_roundtrip_preserves_fbc_s0') def test_roundtrip_preserves_fbc_strict(tmp_path: Path) -> None: """Test that `fbc:strict="true"` of the source survives the round trip. `FBC_ECOLI_CORE_SBML` declares `fbc:strict="true"`. `Document.create_sbml` used to hardcode `setStrict(False)`, which lost it on every round trip. This asserts on `fbc.strict` alone, never on an empty diff: what the rest of the fixture round trips is the subject of the sweep, and one construct which starts to differ must not turn this test red for something it is not about. """ > doc_in, doc_out = roundtrip_document(FBC_ECOLI_CORE_SBML, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:971: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(M_glc__D_e, D-Glucose, SBO:0000247, M_glc__D_e)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ____________________ test_roundtrip_preserves_gene_products ____________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: package_roundtrip = .compare at 0xffff64cdb5e0> def test_roundtrip_preserves_gene_products( package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that the gene products of a model and its associations survive a round trip. `FBC_ECOLI_CORE_SBML` has 137 gene products, every one of them annotated, and 69 reactions with a gene product association. """ > counts, _ = package_roundtrip(FBC_ECOLI_CORE_SBML) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:1128: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(M_glc__D_e, D-Glucose, SBO:0000247, M_glc__D_e)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_roundtrip_loses_only_the_sboterm_of_an_association_node[e_coli_core.xml] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: sbml_path = PosixPath('/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/resources/distrib/e_coli_core.xml') tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_roundtrip_loses_only_the_0') @pytest.mark.parametrize( "sbml_path", [ECOLI_CORE_DISTRIB_SBML, ECOLI_EXPRESSION_SBML], ids=fixture_idfn, ) def test_roundtrip_loses_only_the_sboterm_of_an_association_node( sbml_path: Path, tmp_path: Path ) -> None: """Test that a round trip loses no more of an association than the sboTerm of a node. `Reaction.geneProductAssociation` holds an association as the infix string of its gene product ids, and a string cannot hold what a node of the association carries: `tests/structural.py` therefore compares the metadata of every `and`, `or` and `geneProductRef` node as `nodes`, apart from the string. The two e_coli_core fixtures of `resources/distrib` are the only documents of the corpus whose nodes carry any, and this is the loss that is left; it is not whitelisted, it is pinned here. What is lost has to stay exactly this: an `sboTerm` on an `and` or an `or` node which restates the operator of that node, so the infix string loses nothing which is not derivable from it. Any other metadata on a node - a metaid, an annotation, notes, another term, or anything at all on a `geneProductRef` - would be a real loss and fails this test, and so does a changed association string, which is asserted literally rather than left to the whitelist. """ > doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:1172: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_roundtrip_loses_only_the_sboterm_of_an_association_node[e_coli_core_expression.xml] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: sbml_path = PosixPath('/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/resources/distrib/e_coli_core_expression.xml') tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_roundtrip_loses_only_the_1') @pytest.mark.parametrize( "sbml_path", [ECOLI_CORE_DISTRIB_SBML, ECOLI_EXPRESSION_SBML], ids=fixture_idfn, ) def test_roundtrip_loses_only_the_sboterm_of_an_association_node( sbml_path: Path, tmp_path: Path ) -> None: """Test that a round trip loses no more of an association than the sboTerm of a node. `Reaction.geneProductAssociation` holds an association as the infix string of its gene product ids, and a string cannot hold what a node of the association carries: `tests/structural.py` therefore compares the metadata of every `and`, `or` and `geneProductRef` node as `nodes`, apart from the string. The two e_coli_core fixtures of `resources/distrib` are the only documents of the corpus whose nodes carry any, and this is the loss that is left; it is not whitelisted, it is pinned here. What is lost has to stay exactly this: an `sboTerm` on an `and` or an `or` node which restates the operator of that node, so the infix string loses nothing which is not derivable from it. Any other metadata on a node - a metaid, an annotation, notes, another term, or anything at all on a `geneProductRef` - would be a real loss and fails this test, and so does a changed association string, which is asserted literally rather than left to the whitelist. """ > doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:1172: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _____________________ test_roundtrip_preserves_objectives ______________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: package_roundtrip = .compare at 0xffff64cdb5e0> def test_roundtrip_preserves_objectives( package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that the objective of a model and its flux objectives survive a round trip. `FBC_ECOLI_CORE_SBML` maximizes the biomass reaction, which is the one thing an FBA model is run for. """ > counts, _ = package_roundtrip(FBC_ECOLI_CORE_SBML) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:1206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(M_glc__D_e, D-Glucose, SBO:0000247, M_glc__D_e)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ______________ test_roundtrip_preserves_bounds_charge_and_formula ______________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: package_roundtrip = .compare at 0xffff64cdb5e0> def test_roundtrip_preserves_bounds_charge_and_formula( package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that the flux bounds, charges and chemical formulas of a model survive. The flux bounds of `FBC_ECOLI_CORE_SBML` are what makes its flux space finite; 72 of its 72 species carry a charge and a chemical formula. """ > counts, _ = package_roundtrip(FBC_ECOLI_CORE_SBML) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:1272: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(M_glc__D_e, D-Glucose, SBO:0000247, M_glc__D_e)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ______ test_roundtrip_preserves_the_whole_fbc_content[e_coli_core.xml.gz] ______ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: sbml_path = PosixPath('/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/resources/models/fbc/e_coli_core.xml.gz') constructs = ('fbc.package', 'fbc.strict', 'fbc.geneProduct', 'fbc.geneProductAssociation', 'fbc.fluxBound', 'fbc.charge', ...) package_roundtrip = .compare at 0xffff64cdb5e0> @pytest.mark.parametrize( ("sbml_path", "constructs"), [ # the round trip of Recon3D takes about 25 s, a third of the test run pytest.param( sbml_path, constructs, id=sbml_path.name, marks=[pytest.mark.slow] if sbml_path == FBC_RECON3D_SBML else [], ) for sbml_path, constructs in FBC_FIXTURES ], ) def test_roundtrip_preserves_the_whole_fbc_content( sbml_path: Path, constructs: tuple[str, ...], package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that a round trip of an fbc fixture changes no fbc content at all. Between them the three fixtures carry every fbc construct the parser reads: `FBC_RECON3D_SBML` is the largest model of the repository with 2248 gene products, 10600 flux bounds and 5835 charges, and `FBC_UDC_SBML` is the only one with user-defined constraints. This asserts on every fbc difference, not on the named constructs only, so an fbc construct the round trip *adds* fails it too. """ > counts, differences = package_roundtrip(sbml_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:1837: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(M_glc__D_e, D-Glucose, SBO:0000247, M_glc__D_e)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ________ test_roundtrip_preserves_the_whole_fbc_content[Recon3D.xml.gz] ________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: sbml_path = PosixPath('/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/resources/models/fbc/Recon3D.xml.gz') constructs = ('fbc.package', 'fbc.strict', 'fbc.geneProduct', 'fbc.geneProductAssociation', 'fbc.fluxBound', 'fbc.charge', ...) package_roundtrip = .compare at 0xffff64cdb5e0> @pytest.mark.parametrize( ("sbml_path", "constructs"), [ # the round trip of Recon3D takes about 25 s, a third of the test run pytest.param( sbml_path, constructs, id=sbml_path.name, marks=[pytest.mark.slow] if sbml_path == FBC_RECON3D_SBML else [], ) for sbml_path, constructs in FBC_FIXTURES ], ) def test_roundtrip_preserves_the_whole_fbc_content( sbml_path: Path, constructs: tuple[str, ...], package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that a round trip of an fbc fixture changes no fbc content at all. Between them the three fixtures carry every fbc construct the parser reads: `FBC_RECON3D_SBML` is the largest model of the repository with 2248 gene products, 10600 flux bounds and 5835 charges, and `FBC_UDC_SBML` is the only one with user-defined constraints. This asserts on every fbc difference, not on the named constructs only, so an fbc construct the round trip *adds* fails it too. """ > counts, differences = package_roundtrip(sbml_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:1837: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(M_10fthf_c, 10-Formyltetrahydrofolate, SBO:0000247, M_10fthf_c)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _________ test_roundtrip_flattens_exactly_the_two_pinned_associations __________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_roundtrip_flattens_exactl0') def test_roundtrip_flattens_exactly_the_two_pinned_associations( tmp_path: Path, ) -> None: """Test that the whitelist hides the flattening of a real round trip and nothing else. `gpa-flattening` is the one whitelist entry the fbc round trip relies on, and `R_PFL` and `R_ATPS4r` of `FBC_ECOLI_CORE_SBML` are the only two associations of that fixture it applies to, see `test_gpa_flattening_pins_every_association_libsbml_changes`. Both forms are spelled out here, so a round trip which changes an association in any other way fails this even where the entry would accept it; the entry itself is held to the two strings as well. The entry hides that flattening and nothing more, which the synthetic change at the end shows: one gene of the association written back is replaced, and the comparison reports exactly that reaction. """ > doc_in, doc_out = roundtrip_document(FBC_ECOLI_CORE_SBML, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2000: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:411: in create_sbml self._set_fields(s, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:417: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Species(M_glc__D_e, D-Glucose, SBO:0000247, M_glc__D_e)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_identifiers_org_is_what_pymetadata_does[urn:miriam:chebi:CHEBI%3A33699] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:chebi:CHEBI%3A33699' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ___ test_identifiers_org_is_what_pymetadata_does[urn:miriam:uniprot:P03023] ____ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:uniprot:P03023' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[urn:miriam:obo.go:GO%3A0005623] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:obo.go:GO%3A0005623' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[urn:miriam:biomodels.sbo:SBO%3A0000247] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:biomodels.sbo:SBO%3A0000247' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[urn:miriam:kegg.compound:C00031] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:kegg.compound:C00031' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ____ test_identifiers_org_is_what_pymetadata_does[urn:miriam:taxonomy:9606] ____ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:taxonomy:9606' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ___ test_identifiers_org_is_what_pymetadata_does[urn:miriam:pubmed:10643997] ___ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:pubmed:10643997' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ___ test_identifiers_org_is_what_pymetadata_does[urn:miriam:ec-code:1.1.1.1] ___ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:ec-code:1.1.1.1' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[urn:miriam:reactome:REACT_1234] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:reactome:REACT_1234' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[urn:miriam:sbmlutils.test.collection1:bar] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:sbmlutils.test.collection1:bar' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[urn:miriam:sbmlutils.test.collection1:BAR%3A123] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'urn:miriam:sbmlutils.test.collection1:BAR%3A123' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/chebi/CHEBI:12965] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/chebi/CHEBI:12965' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/uniprot/P03023] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/uniprot/P03023' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/go/GO:0005623] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/go/GO:0005623' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/obo.go/GO:0005623] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/obo.go/GO:0005623' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/biomodels.sbo/SBO:0000247] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/biomodels.sbo/SBO:0000247' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/kegg.compound/C00031] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/kegg.compound/C00031' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/pubmed/10643997] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/pubmed/10643997' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/bigg.metabolite/glc__D] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/bigg.metabolite/glc__D' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/asap/ABE-0000027] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/asap/ABE-0000027' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[https://identifiers.org/taxonomy/9606] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'https://identifiers.org/taxonomy/9606' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/ec-code/1.1.1.1] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/ec-code/1.1.1.1' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/yaaK] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/refseq_synonym/yaaK' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/sbmlutils.test.collection1/1406] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/sbmlutils.test.collection1/1406' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/sbmlutils.test.collection1/XX:0000040] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/sbmlutils.test.collection1/XX:0000040' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/chebi/000000035] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/chebi/000000035' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/BTO:0000131] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/BTO:0000131' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/SBO:0000625] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/SBO:0000625' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/FMA:12274] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/FMA:12274' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/CHEBI:33699] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/CHEBI:33699' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/GO:0005623] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/GO:0005623' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/uniprot:P03023] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/uniprot:P03023' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/kegg.compound:C00031] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/kegg.compound:C00031' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ___________ test_identifiers_org_is_what_pymetadata_does[UO:0000021] ___________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'UO:0000021' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset __________ test_identifiers_org_is_what_pymetadata_does[CHEBI:33699] ___________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'CHEBI:33699' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ___________ test_identifiers_org_is_what_pymetadata_does[GO:0005623] ___________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'GO:0005623' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset __________ test_identifiers_org_is_what_pymetadata_does[SBO:0000247] ___________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'SBO:0000247' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _________ test_identifiers_org_is_what_pymetadata_does[uniprot:P03023] _________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'uniprot:P03023' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex?] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/refseq_synonym/iex?' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex?a=b] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/refseq_synonym/iex?a=b' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex#fragment] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/refseq_synonym/iex#fragment' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex/] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/refseq_synonym/iex/' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex?#] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/refseq_synonym/iex?#' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/chebi/CHEBI:12965/?a=b#c] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/chebi/CHEBI:12965/?a=b#c' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[https://identifiers.org/uniprot/P03023?] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'https://identifiers.org/uniprot/P03023?' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/BTO:0000131?] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/BTO:0000131?' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/BTO:0000131/] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/BTO:0000131/' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/uniprot:P03023?a=b#c] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/uniprot:P03023?a=b#c' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/sbmlutils.test.collection1/1406?] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: resource = 'http://identifiers.org/sbmlutils.test.collection1/1406?' @pytest.mark.parametrize( "resource", [*_URNS, *_CLASSIC_URLS, *_COMPACT_URLS, *_BARE_IDENTIFIERS, *_DECORATED_URLS], ) def test_identifiers_org_is_what_pymetadata_does(resource: str) -> None: """Test the normalization against the canonicalization of pymetadata. `create_model` writes a resource as pymetadata normalizes it whenever the normalization keeps the collection and the term of the resource, and as given when it does not, see `_resource_for_cvterm` of `sbmlutils.metadata.annotator`. Whenever it does normalize, it writes exactly what pymetadata writes, so the whitelist entry has to accept that for each of the four source forms: a MIRIAM URN, a classic identifiers.org URL, the `http` spelling of the compact URL and a bare compact identifier. The expectation is measured, never spelled out here. This is about the whitelist entry, not about which resources are written that way, which is `tests/metadata/test_annotator.py`. """ > url = RDFAnnotation(BQB.IS, resource, validate=False).resource_normalized ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2225: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _____ test_roundtrip_preserves_the_whole_distrib_content[uncertainty.xml] ______ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: sbml_path = PosixPath('/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/resources/distrib/uncertainty.xml') constructs = ('distrib.package', 'distrib.uncertainty', 'distrib.uncertParameter') package_roundtrip = .compare at 0xffff64cdb5e0> @pytest.mark.parametrize( ("sbml_path", "constructs"), DISTRIB_FIXTURES, ids=[sbml_path.name for sbml_path, _ in DISTRIB_FIXTURES], ) def test_roundtrip_preserves_the_whole_distrib_content( sbml_path: Path, constructs: tuple[str, ...], package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that a round trip of a distrib fixture changes no distrib content at all. Between them the fixtures carry every distrib construct: `UNCERTAINTY_SBML` has six uncertainties with every type of uncert parameter and span, a definitionURL, math and a nested `listOfUncertParameters`, `ECOLI_EXPRESSION_SBML` has one on a gene product, `MODEL_SBML` one on a compartment, and the three files of distributions use the csymbols of distrib in the math of core elements. Each is asserted to have the constructs first, so preserving them cannot mean that the fixture has none, and every difference is asserted, not only the ones of the named constructs, so a distrib construct the round trip *adds* fails it too. `DISTRIB_COMP_SBML` is missing from the list on purpose: it is the same model as `DISTRIB_COMP_FLAT_SBML` with a comp port, and it is asserted with both of its packages in `test_roundtrip_of_a_distrib_comp_model_keeps_both_packages`. """ > counts, differences = package_roundtrip(sbml_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2634: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1137: in _set_fields self.create_uncertainties(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1404: in create_uncertainties uncertainty.create_sbml(obj, model) for uncertainty in self.uncertainties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/distrib.py:797: in create_sbml self._set_fields(uncertainty, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(p1, [Uncertainty(UncertParameter(4, 5.0 [mole]), UncertParameter(9, 0.3 [mole]), UncertSpan(15, 2.0 - 8.0 [mole])), Uncertainty(UncertParameter(2, 0.0 [mole]), UncertParameter(3, 1.0 [mole]), UncertParameter(4, 2.0 [mole]), UncertParameter(5, 3.0 [mole]), UncertParameter(6, 4.0 [mole]), UncertParameter(7, 5.0 [mole]), UncertParameter(8, 6.0 [mole]), UncertParameter(9, 7.0 [mole]), UncertParameter(10, 8.0 [mole]), UncertParameter(11, 9.0 [mole])), Uncertainty(UncertSpan(12, -1.0 - 1.0 [mole]), UncertSpan(13, 0.0 - 2.0 [mole]), UncertSpan(14, 1.0 - 3.0 [mole]), UncertSpan(15, 2.0 - 4.0 [mole])), Uncertainty(UncertParameter(0, None [None])), Uncertainty(UncertParameter(1, 0.25 [mole])), Uncertainty(UncertParameter(0, None [mole]))])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _ test_roundtrip_preserves_the_whole_distrib_content[e_coli_core_expression.xml] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: sbml_path = PosixPath('/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/resources/distrib/e_coli_core_expression.xml') constructs = ('distrib.package', 'distrib.uncertainty', 'distrib.uncertParameter') package_roundtrip = .compare at 0xffff64cdb5e0> @pytest.mark.parametrize( ("sbml_path", "constructs"), DISTRIB_FIXTURES, ids=[sbml_path.name for sbml_path, _ in DISTRIB_FIXTURES], ) def test_roundtrip_preserves_the_whole_distrib_content( sbml_path: Path, constructs: tuple[str, ...], package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that a round trip of a distrib fixture changes no distrib content at all. Between them the fixtures carry every distrib construct: `UNCERTAINTY_SBML` has six uncertainties with every type of uncert parameter and span, a definitionURL, math and a nested `listOfUncertParameters`, `ECOLI_EXPRESSION_SBML` has one on a gene product, `MODEL_SBML` one on a compartment, and the three files of distributions use the csymbols of distrib in the math of core elements. Each is asserted to have the constructs first, so preserving them cannot mean that the fixture has none, and every difference is asserted, not only the ones of the named constructs, so a distrib construct the round trip *adds* fails it too. `DISTRIB_COMP_SBML` is missing from the list on purpose: it is the same model as `DISTRIB_COMP_FLAT_SBML` with a comp port, and it is asserted with both of its packages in `test_roundtrip_of_a_distrib_comp_model_keeps_both_packages`. """ > counts, differences = package_roundtrip(sbml_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2634: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ________ test_roundtrip_preserves_the_whole_distrib_content[model.xml] _________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: sbml_path = PosixPath('/builddir/build/BUILD/python-sbmlutils-0.17.0-build/BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/resources/examples/model.xml') constructs = ('distrib.package', 'distrib.uncertainty', 'distrib.uncertParameter') package_roundtrip = .compare at 0xffff64cdb5e0> @pytest.mark.parametrize( ("sbml_path", "constructs"), DISTRIB_FIXTURES, ids=[sbml_path.name for sbml_path, _ in DISTRIB_FIXTURES], ) def test_roundtrip_preserves_the_whole_distrib_content( sbml_path: Path, constructs: tuple[str, ...], package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that a round trip of a distrib fixture changes no distrib content at all. Between them the fixtures carry every distrib construct: `UNCERTAINTY_SBML` has six uncertainties with every type of uncert parameter and span, a definitionURL, math and a nested `listOfUncertParameters`, `ECOLI_EXPRESSION_SBML` has one on a gene product, `MODEL_SBML` one on a compartment, and the three files of distributions use the csymbols of distrib in the math of core elements. Each is asserted to have the constructs first, so preserving them cannot mean that the fixture has none, and every difference is asserted, not only the ones of the named constructs, so a distrib construct the round trip *adds* fails it too. `DISTRIB_COMP_SBML` is missing from the list on purpose: it is the same model as `DISTRIB_COMP_FLAT_SBML` with a comp port, and it is asserted with both of its packages in `test_roundtrip_of_a_distrib_comp_model_keeps_both_packages`. """ > counts, differences = package_roundtrip(sbml_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2634: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(k1, SBO:0000009, meta_k1)' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) ______________ test_roundtrip_preserves_the_submodels_of_icg_body ______________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: package_roundtrip = .compare at 0xffff64cdb5e0> def test_roundtrip_preserves_the_submodels_of_icg_body( package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that the submodel of `COMP_ICG_BODY` survives a round trip. The model is a whole-body PBPK model whose liver is a submodel of an external model definition, so it has exactly one ``, with an id and a name. """ > comparison = package_roundtrip(COMP_ICG_BODY) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2857: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ________________ test_roundtrip_preserves_the_ports_of_icg_body ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: package_roundtrip = .compare at 0xffff64cdb5e0> def test_roundtrip_preserves_the_ports_of_icg_body( package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that the 16 ports of `COMP_ICG_BODY` survive a round trip. Every port has an id, a name, a metaid and an sboTerm of its own, and each references a parameter or a species of the model by `idRef`. """ > comparison = package_roundtrip(COMP_ICG_BODY) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2884: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _________________ test_roundtrip_writes_each_port_exactly_once _________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_roundtrip_writes_each_por0') def test_roundtrip_writes_each_port_exactly_once(tmp_path: Path) -> None: """Test that a port read is written once, not once per way of writing it. `sbmlutils.factory` writes a port from the `ports` of the model and from the `port=True`/`port=Port(...)` shorthand of the element it references, and an element which carried both would be given two ports. The parser reads a port into the `ports` of the model only: the list keeps the port's own id, name, metaid, sboTerm and order, and it does not depend on the referenced element accepting a `port=` keyword, which many do not. """ > doc_in, doc_out = roundtrip_document(COMP_ICG_BODY, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:2895: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _____________ test_roundtrip_preserves_external_model_definitions ______________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: package_roundtrip = .compare at 0xffff64cdb5e0> def test_roundtrip_preserves_external_model_definitions( package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that a `` survives with its attributes. `COMP_ICG_BODY` names its liver model in a file of its own, `MINIMAL_MODEL_COMP_SBML` names five, and the comparison compares `source`, `modelRef` and `md5` of each, with its metadata. """ for sbml_path, count in [(COMP_ICG_BODY, 1), (MINIMAL_MODEL_COMP_SBML, 5)]: > comparison = package_roundtrip(sbml_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:3329: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ____________ test_roundtrip_preserves_the_comp_content_of_icg_body _____________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: package_roundtrip = .compare at 0xffff64cdb5e0> def test_roundtrip_preserves_the_comp_content_of_icg_body( package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that the whole comp content of `COMP_ICG_BODY` survives a round trip. The model is a whole-body PBPK model whose liver is a submodel of an external model definition: one submodel, 16 ports, six replaced elements and one external model definition, which is every comp construct this fixture has. Each is asserted to be in the document first, so preserving them cannot mean that the fixture has none, and every comp difference is asserted, not only those of the named constructs, so comp content the round trip *adds* fails it too. """ > counts, differences = package_roundtrip(COMP_ICG_BODY) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:3442: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _____________ test_roundtrip_of_a_flat_model_gains_no_comp_content _____________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: package_roundtrip = .compare at 0xffff64cdb5e0> def test_roundtrip_of_a_flat_model_gains_no_comp_content( package_roundtrip: Callable[[Path], Comparison], ) -> None: """Test that a model without comp does not gain comp content. `COMP_ICG_BODY_FLAT` is `COMP_ICG_BODY` with its submodel resolved into it: it declares no comp package and has no comp element at all, and the round trip of it must write none either. """ > counts, differences = package_roundtrip(COMP_ICG_BODY_FLAT) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:3458: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:1096: in compare doc_in, doc_out = roundtrip_document(sbml_path, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/structural.py:626: in roundtrip_document create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ______ test_roundtrip_of_an_l3v1_comp_model_validates_at_its_own_version _______ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_roundtrip_of_an_l3v1_comp0') def test_roundtrip_of_an_l3v1_comp_model_validates_at_its_own_version( tmp_path: Path, ) -> None: """Test what libsbml makes of an external model definition of another version. `COMP_ICG_BODY` is an L3V1 document whose liver submodel is the L3V1 file `icg_liver.xml` next to it. Written at L3V1, with that file beside it, the round trip validates without an error. Written at L3V2, libsbml refuses to resolve the reference, error 1020304 (`External models must be L3`, whose message says the document found at the source "was not SBML Level 3 Version 1"), and the submodel which names it is then unresolvable as well, error 1020615 (and the flattening fails, error 1090104): libsbml requires the referenced document at the level and version of the document which references it. The round trip preserves the reference and does not touch the file it names, so the level of the document written is what decides this, and a caller who needs the reference to resolve writes the level of the source. """ shutil.copy(COMP_ICG_BODY.parent / "icg_liver.xml", tmp_path / "icg_liver.xml") model = sbml_to_model(COMP_ICG_BODY) errors: dict[int, list[int]] = {} for version in (1, 2): out = tmp_path / f"icg_body-l3v{version}.xml" > create_model( model=model, filepath=out, sbml_level=3, sbml_version=version, validate=False, ) tests/test_package_roundtrip.py:3555: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _____________ test_key_value_pair_writes_every_field_it_can_carry ______________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_key_value_pair_writes_eve0') def test_key_value_pair_writes_every_field_it_can_carry(tmp_path: Path) -> None: """Test that the metadata of a key-value pair is written, not only its key.""" > sbml_path = _key_value_pair_metadata_sbml(tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:3657: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:3632: in _key_value_pair_metadata_sbml create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1141: in _set_fields self.create_key_value_pairs(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1451: in create_key_value_pairs return KeyValuePair.create_pairs(self.keyValuePairs, sbase, model, self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1605: in create_pairs return [pair.create_sbml(sbase, model) for pair in pairs] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1633: in create_sbml self._set_fields(kvp, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(k, [KeyValuePair(kind = test)])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(k, [KeyValuePair(kind = test)])' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(k, [KeyValuePair(kind = test)])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) __________ test_roundtrip_preserves_the_metadata_of_a_key_value_pair ___________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_roundtrip_preserves_the_m0') def test_roundtrip_preserves_the_metadata_of_a_key_value_pair(tmp_path: Path) -> None: """Test that the whole key-value pair survives a round trip. `structural_diff` compares the `key`, `value` and `uri` of a pair and the metadata of every element which has its own, so it sees each of the six fields. """ > sbml_path = _key_value_pair_metadata_sbml(tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_roundtrip.py:3689: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_roundtrip.py:3632: in _key_value_pair_metadata_sbml create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:806: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:924: in _fill_sbml self._create_lists( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:969: in _create_lists create_objects(model, obj_iter=objects, key=attr) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:118: in create_objects sbml_obj: libsbml.SBase | None = _create_object(obj, model) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:88: in _create_object return obj.create_sbml(container) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:143: in create_sbml self._set_fields(obj, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/core_elements.py:169: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/units.py:614: in _set_fields super()._set_fields(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1141: in _set_fields self.create_key_value_pairs(sbase, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1451: in create_key_value_pairs return KeyValuePair.create_pairs(self.keyValuePairs, sbase, model, self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1605: in create_pairs return [pair.create_sbml(sbase, model) for pair in pairs] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1633: in create_sbml self._set_fields(kvp, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Model' WARNING sbmlutils.factory._core:_core.py:1112 'name' should be set on 'Parameter(k, [KeyValuePair(kind = test)])' WARNING sbmlutils.factory._core:_core.py:1117 'sboTerm' should be set on 'Parameter(k, [KeyValuePair(kind = test)])' WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset ERROR sbmlutils.factory._core:_core.py:90 Error creating SBML object for 'Parameter(k, [KeyValuePair(kind = test)])' ERROR sbmlutils.factory._core:_core.py:91 Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) _______________________ test_comp_semantics_of_icg_body ________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_comp_semantics_of_icg_bod0') @requires_roadrunner def test_comp_semantics_of_icg_body(tmp_path: Path) -> None: """Test that the round trip of `COMP_ICG_BODY` flattens and simulates like the original. The model is a whole-body PBPK model whose liver is a submodel of an external model definition, the one model of the repository with a `comp:source` to another file. The flattened original is asserted to hold the content of that submodel first, so that an agreement cannot mean that nothing was resolved. """ assert [source.name for source in external_sources(COMP_ICG_BODY)] == [ "icg_liver.xml" ] > roundtrip_path = roundtrip_comp_document(COMP_ICG_BODY, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_semantics.py:424: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_semantics.py:161: in roundtrip_comp_document return roundtrip_file(sbml_path, out_dir, doc.getLevel(), doc.getVersion()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_semantics.py:124: in roundtrip_file create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _____ test_comp_semantic_diff_sees_a_damaged_round_trip[drop the submodel] _____ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: damage = expected = 'the round trip does not flatten' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_comp_semantic_diff_sees_a0') @requires_roadrunner @pytest.mark.parametrize( ("damage", "expected"), [(damage, expected) for _, damage, expected in COMP_DAMAGES], ids=[name for name, _, _ in COMP_DAMAGES], ) def test_comp_semantic_diff_sees_a_damaged_round_trip( damage: Callable[[libsbml.SBMLDocument], None], expected: str, tmp_path: Path ) -> None: """Test that the comparison of layer 2 reports a damaged round trip. A comparison which reports nothing on a damaged document verifies nothing, so each damage is applied to the round trip of `COMP_ICG_BODY`, which the comparison reports as unchanged undamaged, see `test_comp_semantics_of_icg_body`. Dropping the submodel leaves the six replaced elements referring to a submodel which is not there, which libsbml refuses to flatten; dropping a replaced element leaves the liver with its own value, which changes the flat model. """ > roundtrip_path = roundtrip_comp_document(COMP_ICG_BODY, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_semantics.py:540: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_semantics.py:161: in roundtrip_comp_document return roundtrip_file(sbml_path, out_dir, doc.getLevel(), doc.getVersion()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_semantics.py:124: in roundtrip_file create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_comp_semantic_diff_sees_a_damaged_round_trip[drop the replaced element of the liver plasma volume] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: damage = .damage at 0xffff67e37320> expected = "differs in selection 'LI__bil_ext'" tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_comp_semantic_diff_sees_a1') @requires_roadrunner @pytest.mark.parametrize( ("damage", "expected"), [(damage, expected) for _, damage, expected in COMP_DAMAGES], ids=[name for name, _, _ in COMP_DAMAGES], ) def test_comp_semantic_diff_sees_a_damaged_round_trip( damage: Callable[[libsbml.SBMLDocument], None], expected: str, tmp_path: Path ) -> None: """Test that the comparison of layer 2 reports a damaged round trip. A comparison which reports nothing on a damaged document verifies nothing, so each damage is applied to the round trip of `COMP_ICG_BODY`, which the comparison reports as unchanged undamaged, see `test_comp_semantics_of_icg_body`. Dropping the submodel leaves the six replaced elements referring to a submodel which is not there, which libsbml refuses to flatten; dropping a replaced element leaves the liver with its own value, which changes the flat model. """ > roundtrip_path = roundtrip_comp_document(COMP_ICG_BODY, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_semantics.py:540: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_semantics.py:161: in roundtrip_comp_document return roundtrip_file(sbml_path, out_dir, doc.getLevel(), doc.getVersion()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_semantics.py:124: in roundtrip_file create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset _ test_comp_semantic_diff_sees_a_damaged_round_trip[drop the replaced element of the liver plasma concentration] _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3.14/site-packages/urllib3/connection.py:239: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'registry.api.identifiers.org', port = 443 family = , type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib64/python3.14/socket.py:989: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/resolutionApi/getResolverDataset', body = None headers = {'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, zstd', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=30, read=30, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {}, destination_scheme = None, conn = None release_this_conn = True, http_tunnel_required = False, err = None clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): # URLs starting with / are inherently schemeless. url = to_str(_encode_target(url)) destination_scheme = None else: parsed_url = parse_url(url) destination_scheme = parsed_url.scheme url = to_str(parsed_url._replace(fragment=None).url) if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) timeout_obj = self._get_timeout(timeout) try: # Request a connection from the queue. conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:793: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:494: in _make_request raise new_e /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:470: in _make_request self._validate_conn(conn) /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:1125: in _validate_conn conn.connect() /usr/lib/python3.14/site-packages/urllib3/connection.py:827: in connect self.sock = sock = self._new_conn() ^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3.14/site-packages/urllib3/connection.py:246: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3.14/site-packages/requests/adapters.py:645: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:886: in urlopen return self.urlopen( /usr/lib/python3.14/site-packages/urllib3/connectionpool.py:847: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/resolutionApi/getResolverDataset', response = None error = NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/urllib3/util/retry.py:555: MaxRetryError During handling of the above exception, another exception occurred: url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: > response = get_session().get(url, params=params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.14/site-packages/requests/sessions.py:605: in get return self.request("GET", url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:592: in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/requests/sessions.py:706: in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:64: in send return super().send( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=30, read=30, total=None), verify = True, cert = None proxies = OrderedDict() def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/requests/adapters.py:678: ConnectionError The above exception was the direct cause of the following exception: damage = .damage at 0xffff67e37480> expected = 'selections differ' tmp_path = PosixPath('/tmp/pytest-of-mockbuild/pytest-0/test_comp_semantic_diff_sees_a2') @requires_roadrunner @pytest.mark.parametrize( ("damage", "expected"), [(damage, expected) for _, damage, expected in COMP_DAMAGES], ids=[name for name, _, _ in COMP_DAMAGES], ) def test_comp_semantic_diff_sees_a_damaged_round_trip( damage: Callable[[libsbml.SBMLDocument], None], expected: str, tmp_path: Path ) -> None: """Test that the comparison of layer 2 reports a damaged round trip. A comparison which reports nothing on a damaged document verifies nothing, so each damage is applied to the round trip of `COMP_ICG_BODY`, which the comparison reports as unchanged undamaged, see `test_comp_semantics_of_icg_body`. Dropping the submodel leaves the six replaced elements referring to a submodel which is not there, which libsbml refuses to flatten; dropping a replaced element leaves the liver with its own value, which changes the flat model. """ > roundtrip_path = roundtrip_comp_document(COMP_ICG_BODY, tmp_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_semantics.py:540: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/test_package_semantics.py:161: in roundtrip_comp_document return roundtrip_file(sbml_path, out_dir, doc.getLevel(), doc.getVersion()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tests/test_package_semantics.py:124: in roundtrip_file create_model( ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1769: in create_model ).create_sbml() ^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1551: in create_sbml return self._create_sbml() ^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:1615: in _create_sbml sbml_model: libsbml.Model = self.model.create_sbml(self.doc) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:805: in create_sbml return self._create_sbml(doc) ^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:818: in _create_sbml self._fill_sbml(model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/model.py:862: in _fill_sbml self._set_fields(model, model) ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1131: in _set_fields processed_annotations = Sbase._process_annotations(self.annotations) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../BUILDROOT/usr/lib/python3.14/site-packages/sbmlutils/factory/_core.py:1039: in _process_annotations annotations.append(Annotation.from_tuple(annotation_obj)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:342: in from_tuple return RDFAnnotation(qualifier=qualifier, resource=resource) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:290: in __init__ self.term = self.shorten_compact_term( /usr/lib/python3.14/site-packages/pymetadata/core/annotation.py:320: in shorten_compact_term namespace = get_registry().ns_dict.get(collection, None) ^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:306: in get_registry _REGISTRY = Registry() ^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:189: in __init__ self.ns_dict = self.update() ^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:214: in update return Registry.update_registry(registry_path=self.registry_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/lib/python3.14/site-packages/pymetadata/webservices/registry.py:248: in update_registry namespaces = get_json(Registry.URL)["payload"]["namespaces"] ^^^^^^^^^^^^^^^^^^^^^^ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset' params = None def get_json(url: str, params: dict[str, str] | None = None) -> Any: """Query a url and return the parsed JSON response. Args: url: url to query params: query parameters, encoded and appended to the url Returns: The parsed JSON response. Raises: WebserviceNotFoundError: if the service answers 404 WebserviceError: if the service cannot be reached, answers with a status other than 200, or does not answer with JSON """ logger.debug("Query: %s %s", url, params or "") try: response = get_session().get(url, params=params) except requests.RequestException as err: # no network, DNS failure, timeout, too many retries, ... > raise WebserviceError(f"Service is not reachable for '{url}': {err}") from err E pymetadata.webservices.webservice.WebserviceError: Service is not reachable for 'https://registry.api.identifiers.org/resolutionApi/getResolverDataset': HTTPSConnectionPool(host='registry.api.identifiers.org', port=443): Max retries exceeded with url: /resolutionApi/getResolverDataset (Caused by NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3.14/site-packages/pymetadata/webservices/webservice.py:139: WebserviceError ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset WARNING urllib3.connectionpool:connectionpool.py:874 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError("HTTPSConnection(host='registry.api.identifiers.org', port=443): Failed to resolve 'registry.api.identifiers.org' ([Errno -3] Temporary failure in name resolution)")': /resolutionApi/getResolverDataset =========================== short test summary info ============================ FAILED tests/examples/test_example_scripts.py::test_example_script[examples.converters.xpp] FAILED tests/examples/test_example_scripts.py::test_example_script[examples.distrib.distrib_packages_examples] FAILED tests/examples/test_example_scripts.py::test_example_script[examples.distrib.distrib_uncertainty] FAILED tests/examples/test_example_scripts.py::test_example_script[examples.interpolation.driving] FAILED tests/examples/test_example_scripts.py::test_example_script[examples.interpolation.interpolation] FAILED tests/examples/test_example_scripts.py::test_example_script[examples.interpolation.pancreas] FAILED tests/examples/test_example_scripts.py::test_example_script[examples.merge_models.merge_models] FAILED tests/examples/test_example_scripts.py::test_example_script[examples.tiny.simulation] FAILED tests/examples/test_examples.py::test_create_example_create[examples.tutorial.model_composition] FAILED tests/examples/test_examples.py::test_create_example_create[examples.demo.demo] FAILED tests/examples/test_examples.py::test_create_example_create[examples.tiny.tiny] FAILED tests/examples/test_examples.py::test_create_example_models[examples.annotation] FAILED tests/examples/test_examples.py::test_create_example_models[examples.fbc.fbc_v2] FAILED tests/examples/test_examples.py::test_create_example_models[examples.fbc.fbc_mass_charge] FAILED tests/examples/test_examples.py::test_create_example_models[examples.model] FAILED tests/examples/test_examples.py::test_create_example_models[examples.parameter] FAILED tests/io/test_sbml.py::test_read_sbml_reads_a_file_without_an_xml_declaration[model] FAILED tests/io/test_sbml.py::test_read_sbml_reads_a_file_without_an_xml_declaration[comp-library] FAILED tests/metadata/test_annotator.py::test_create_annotation - pymetadata.... FAILED tests/metadata/test_annotator.py::test_model_annotation - pymetadata.w... FAILED tests/metadata/test_annotator.py::test_demo_annotation - pymetadata.we... FAILED tests/metadata/test_annotator.py::test_galactose_annotation - pymetada... FAILED tests/metadata/test_annotator.py::test_annotation_resource_which_cannot_be_normalized_is_written_as_given[urn:miriam:sbmlutils.test.collection1] FAILED tests/metadata/test_annotator.py::test_annotation_resource_which_cannot_be_normalized_is_written_as_given[urn:miriam:sbmlutils.test.collection1:] FAILED tests/metadata/test_annotator.py::test_annotation_resource_which_cannot_be_normalized_is_written_as_given[sbmlutils.test.collection1/] FAILED tests/metadata/test_annotator.py::test_annotation_resource_which_cannot_be_normalized_is_written_as_given[urn:miriam::bar] FAILED tests/metadata/test_annotator.py::test_annotation_resource_of_a_known_collection_is_normalized[chebi/CHEBI:12965-https://identifiers.org/CHEBI:12965] FAILED tests/metadata/test_annotator.py::test_annotation_resource_of_a_known_collection_is_normalized[urn:miriam:chebi:CHEBI%3A33699-https://identifiers.org/CHEBI:33699] FAILED tests/metadata/test_annotator.py::test_annotation_resource_of_a_known_collection_is_normalized[http://identifiers.org/BTO:0000131-https://identifiers.org/BTO:0000131] FAILED tests/metadata/test_annotator.py::test_annotation_resource_of_a_known_collection_is_normalized[UO:0000021-https://identifiers.org/UO:0000021] FAILED tests/metadata/test_annotator.py::test_annotation_resource_of_a_known_collection_is_normalized[http://identifiers.org/sbmlutils.test.collection1/1406-https://identifiers.org/sbmlutils.test.collection1/1406] FAILED tests/metadata/test_annotator.py::test_annotation_resource_of_a_known_collection_is_normalized[http://identifiers.org/sbmlutils.test.collection1/XX:0000040-https://identifiers.org/sbmlutils.test.collection1/XX:0000040] FAILED tests/metadata/test_annotator.py::test_annotation_resource_of_a_known_collection_is_normalized[https://identifiers.org/SBMLUTILS.TEST.COLLECTION1:0000012-https://identifiers.org/SBMLUTILS.TEST.COLLECTION1:0000012] FAILED tests/metadata/test_annotator.py::test_annotation_resource_of_a_known_collection_is_normalized[http://identifiers.org/chebi/000000035-https://identifiers.org/chebi/000000035] FAILED tests/metadata/test_annotator.py::test_annotation_resource_of_a_known_collection_is_normalized[urn:miriam:sbmlutils.test.collection1:bar-https://identifiers.org/sbmlutils.test.collection1/bar] FAILED tests/metadata/test_annotator.py::test_annotation_losses_are_reported_once_per_collection FAILED tests/metadata/test_annotator.py::test_annotation_losses_do_not_leak_between_documents FAILED tests/metadata/test_annotator.py::test_annotation_loss_without_a_collection_is_grouped_as_such FAILED tests/metadata/test_annotator.py::test_annotation_loss_outside_a_document_is_reported_per_resource FAILED tests/test_construction_diagnostics.py::test_retained_annotation_is_informational FAILED tests/test_distrib.py::test_sabiork_uncertainty - pymetadata.webservic... FAILED tests/test_factory.py::test_reaction_modifier_keeps_sbase_fields - pym... FAILED tests/test_factory.py::test_reaction_reactant_keeps_name_notes_and_annotations FAILED tests/test_factory.py::test_an_annotation_which_is_neither_an_annotation_nor_a_tuple_raises[second] FAILED tests/test_package_roundtrip.py::test_roundtrip_document_returns_both_documents FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_fbc_strict FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_gene_products FAILED tests/test_package_roundtrip.py::test_roundtrip_loses_only_the_sboterm_of_an_association_node[e_coli_core.xml] FAILED tests/test_package_roundtrip.py::test_roundtrip_loses_only_the_sboterm_of_an_association_node[e_coli_core_expression.xml] FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_objectives FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_bounds_charge_and_formula FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_the_whole_fbc_content[e_coli_core.xml.gz] FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_the_whole_fbc_content[Recon3D.xml.gz] FAILED tests/test_package_roundtrip.py::test_roundtrip_flattens_exactly_the_two_pinned_associations FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:chebi:CHEBI%3A33699] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:uniprot:P03023] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:obo.go:GO%3A0005623] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:biomodels.sbo:SBO%3A0000247] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:kegg.compound:C00031] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:taxonomy:9606] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:pubmed:10643997] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:ec-code:1.1.1.1] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:reactome:REACT_1234] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:sbmlutils.test.collection1:bar] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[urn:miriam:sbmlutils.test.collection1:BAR%3A123] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/chebi/CHEBI:12965] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/uniprot/P03023] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/go/GO:0005623] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/obo.go/GO:0005623] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/biomodels.sbo/SBO:0000247] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/kegg.compound/C00031] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/pubmed/10643997] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/bigg.metabolite/glc__D] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/asap/ABE-0000027] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[https://identifiers.org/taxonomy/9606] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/ec-code/1.1.1.1] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/yaaK] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/sbmlutils.test.collection1/1406] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/sbmlutils.test.collection1/XX:0000040] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/chebi/000000035] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/BTO:0000131] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/SBO:0000625] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/FMA:12274] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/CHEBI:33699] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/GO:0005623] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/uniprot:P03023] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/kegg.compound:C00031] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[UO:0000021] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[CHEBI:33699] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[GO:0005623] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[SBO:0000247] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[uniprot:P03023] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex?] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex?a=b] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex#fragment] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex/] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/refseq_synonym/iex?#] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/chebi/CHEBI:12965/?a=b#c] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[https://identifiers.org/uniprot/P03023?] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/BTO:0000131?] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/BTO:0000131/] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/uniprot:P03023?a=b#c] FAILED tests/test_package_roundtrip.py::test_identifiers_org_is_what_pymetadata_does[http://identifiers.org/sbmlutils.test.collection1/1406?] FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_the_whole_distrib_content[uncertainty.xml] FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_the_whole_distrib_content[e_coli_core_expression.xml] FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_the_whole_distrib_content[model.xml] FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_the_submodels_of_icg_body FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_the_ports_of_icg_body FAILED tests/test_package_roundtrip.py::test_roundtrip_writes_each_port_exactly_once FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_external_model_definitions FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_the_comp_content_of_icg_body FAILED tests/test_package_roundtrip.py::test_roundtrip_of_a_flat_model_gains_no_comp_content FAILED tests/test_package_roundtrip.py::test_roundtrip_of_an_l3v1_comp_model_validates_at_its_own_version FAILED tests/test_package_roundtrip.py::test_key_value_pair_writes_every_field_it_can_carry FAILED tests/test_package_roundtrip.py::test_roundtrip_preserves_the_metadata_of_a_key_value_pair FAILED tests/test_package_semantics.py::test_comp_semantics_of_icg_body - pym... FAILED tests/test_package_semantics.py::test_comp_semantic_diff_sees_a_damaged_round_trip[drop the submodel] FAILED tests/test_package_semantics.py::test_comp_semantic_diff_sees_a_damaged_round_trip[drop the replaced element of the liver plasma volume] FAILED tests/test_package_semantics.py::test_comp_semantic_diff_sees_a_damaged_round_trip[drop the replaced element of the liver plasma concentration] ERROR tests/test_distrib.py::test_uncert_child_writes_meta_id_and_sbo_term[up_mean] ERROR tests/test_distrib.py::test_uncert_child_writes_meta_id_and_sbo_term[up_range] ERROR tests/test_distrib.py::test_uncert_child_writes_id_and_name[up_mean] - ... ERROR tests/test_distrib.py::test_uncert_child_writes_id_and_name[up_range] ERROR tests/test_distrib.py::test_uncert_child_writes_notes[up_mean] - pymeta... ERROR tests/test_distrib.py::test_uncert_child_writes_notes[up_range] - pymet... ERROR tests/test_distrib.py::test_uncert_child_writes_annotations[up_mean] - ... ERROR tests/test_distrib.py::test_uncert_child_writes_annotations[up_range] ERROR tests/test_distrib.py::test_uncert_child_writes_key_value_pairs[up_mean] ERROR tests/test_distrib.py::test_uncert_child_writes_key_value_pairs[up_range] 119 failed, 1327 passed, 75 skipped, 3 deselected, 10 errors in 436.42s (0:07:16) error: Bad exit status from /var/tmp/rpm-tmp.u9hcyM (%check) Bad exit status from /var/tmp/rpm-tmp.u9hcyM (%check) RPM build errors: Finish: rpmbuild python-sbmlutils-0.17.0-1.fc44.src.rpm Finish: build phase for python-sbmlutils-0.17.0-1.fc44.src.rpm INFO: chroot_scan: 1 files copied to /var/lib/copr-rpmbuild/results/chroot_scan INFO: /var/lib/mock/fedora-44-aarch64-1792824741.766395/root/var/log/dnf5.log INFO: chroot_scan: creating tarball /var/lib/copr-rpmbuild/results/chroot_scan.tar.gz /bin/tar: Removing leading `/' from member names ERROR: Exception(/var/lib/copr-rpmbuild/results/python-sbmlutils-0.17.0-1.fc44.src.rpm) Config(fedora-44-aarch64) 7 minutes 41 seconds INFO: Results and/or logs in: /var/lib/copr-rpmbuild/results INFO: Cleaning up build root ('cleanup_on_failure=True') Start: clean chroot INFO: unmounting tmpfs. Finish: clean chroot ERROR: Command failed: # /usr/bin/systemd-nspawn -q -M 17e53fd576574df19dadc1addad44148 -D /var/lib/mock/fedora-44-aarch64-1792824741.766395/root -a -u mockbuild --capability=cap_ipc_lock --capability=cap_ipc_lock --bind=/dev/btrfs-control --bind=/dev/mapper/control --bind=/dev/fuse --bind=/dev/loop-control --bind=/dev/loop0 --bind=/dev/loop1 --bind=/dev/loop2 --bind=/dev/loop3 --bind=/dev/loop4 --bind=/dev/loop5 --bind=/dev/loop6 --bind=/dev/loop7 --bind=/dev/loop8 --bind=/dev/loop9 --bind=/dev/loop10 --bind=/dev/loop11 --resolv-conf=off --resolv-conf=off --console=pipe --setenv=TERM=vt100 --setenv=SHELL=/bin/bash --setenv=HOME=/builddir --setenv=HOSTNAME=mock --setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin '--setenv=PROMPT_COMMAND=printf "\033]0;\007"' '--setenv=PS1= \s-\v\$ ' --setenv=LANG=C.UTF-8 bash --login -c '/usr/bin/rpmbuild -ba --noprep --noclean --target aarch64 /builddir/build/originals/python-sbmlutils.spec' Copr build error: Build failed