Mock Version: 3.5 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -bs --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1001gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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']unshare_net=TrueprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', '9bb2b07b617348938a1f4bbf9dae49f3', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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', '--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', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -bs --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1679961600 Wrote: /builddir/build/SRPMS/python-kcapi-1.1.2-1.fc39.src.rpm Child return code was: 0 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1001gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', '90aecabbb4f146098d58dd82a56dff55', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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', '--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', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1679961600 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.m7NSbf + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf kcapi-1.1.2 + /usr/lib/rpm/rpmuncompress -x /builddir/build/SOURCES/kcapi-1.1.2.tar.gz + STATUS=0 + '[' 0 -ne 0 ']' + cd kcapi-1.1.2 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.9oYSth + umask 022 + cd /builddir/build/BUILD + cd kcapi-1.1.2 + 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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + echo '(python3dist(toml) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/kcapi-1.1.2/.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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + TMPDIR=/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir + RPM_TOXENV=py311 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/kcapi-1.1.2/pyproject-wheeldir Handling setuptools>=61.0 from build-system.requires Requirement not satisfied: setuptools>=61.0 Exiting dependency generation pass: build backend + rm -rfv '*.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-kcapi-1.1.2-1.fc39.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1001gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', '5e26c9b476084577a4b220583198400d', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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', '--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', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1679961600 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.yZ36Gt + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf kcapi-1.1.2 + /usr/lib/rpm/rpmuncompress -x /builddir/build/SOURCES/kcapi-1.1.2.tar.gz + STATUS=0 + '[' 0 -ne 0 ']' + cd kcapi-1.1.2 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.6N0SvS + umask 022 + cd /builddir/build/BUILD + cd kcapi-1.1.2 + 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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + echo '(python3dist(toml) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/kcapi-1.1.2/.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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + TMPDIR=/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir + RPM_TOXENV=py311 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/kcapi-1.1.2/pyproject-wheeldir Handling setuptools>=61.0 from build-system.requires Requirement satisfied: setuptools>=61.0 (installed: setuptools 67.6.1) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'readme' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `readme = '# Keycloak API\n\nPython module to automate Keycloak or Red Hat Single Sign-On (RHSSO) configuration.\n\n## How To Install\n\n```sh\npip install kcapi\n```\n\n\n## Testing\n\nTo run the test you would need a Keycloak instance, you can run one locally or in the [cloud]( https://developers.redhat.com/developer-sandbox/get-started) then you just have to follow this steps: \n\n```shell script\npython3.10 -m venv .venv\nsource .venv/bin/activate\npip install requests\n\n# Setup SSO server - go to https://developers.redhat.com/developer-sandbox/get-started,\n# launch sandbox environment, +Add, select some "Red Hat Single Sign-On..." template.\nexport KC_USER=admin\nexport KC_PASSWORD=admin_password\nexport KC_REALM=myrealm # do not use master realm, it cannot be removed\nexport KC_ENDPOINT=https://my-first-sso-me-me-dev.apps.sandbox.x8i5.p1.openshiftapps.com\n\npython -m unittest\n```\n\n\n## API\n\n### OpenID\n\nThis class takes care of OpenID login using [password owner credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3) flow.\n\n\n#### Constructor\n\n```python\nfrom rhsso import OpenID\n\noid_client = OpenID({\n "client_id": "admin-cli",\n "username": USER,\n "password": PASSWORD,\n "grant_type":"password",\n "realm" : "master"\n }, endpoint)\n```\n\n- **client_id**: Client Identifier in Keycloak.\n- **username**: Login username for the Realm.\n- **password**: Login password for the Realm.\n- **grant_type**: The grant type you want to use (usually ``password``).\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n##### getToken\n\nThis will initiate a session with the Keycloak server and will return a OpenID token back.\n\n```python\noid_client.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n\n##### createAdminClient\n\nThis static method should be used in order to access the master Realm in Keycloak.\n\n```python\n oidc = OpenID.createAdminClient(self.USER, self.PASSWORD)\n oidc.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n### Keycloak\n\nThis class builds all the Keycloak configuration REST resources by using REST conventions we can target the majority of Keycloak services.\n\n#### Constructor\n\n```Python\nkc = Keycloak(token, self.ENDPOINT)\n```\n\nThe constructor takes two parameters:\n\n- **token**: A token with enough priviledge to perform the desired operation.\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n#### build\nThis methods build a REST client (capabilities detailed below) targeting a specific Keycloak REST resource.\n\n```python\ngroups = kc.build(\'groups\', \'my_realm\')\n\n# Create a group called DC\nstate = groups.create({"name": "DC"}).isOk()\n\n```\n> In this example we build the \'groups\' API for ``my_realm`` Realm.\n\n##### Supported Resources\n\nHere is a quick list of supported resources:\n\n- **users**: [users API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_user).\n- **clients**: [client API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_client). \n- **groups**: [groups API](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n- **roles**: [roles API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_role_for_the_realm_or_client_2)\n- **identity-provider**: [identity provider API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_get_identity_providers)\n\n\n> As long as you find a REST endpoint that follow the standard you can use this method to build a client around it, an example of this is the non well documented ``components`` endpoint.\n\n- **components**: This API allows you configure things like [user federation](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/user-storage-federation) or [Realm keys](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/admin_permissions#realm_keys).\n\n- **authentication**: Provide access to built-in and/or custom authentication flows.\n
\n\n#### admin\nSimilar to the ``build`` method but the client points to the ``master`` realm, allowing us operation such as realm creation.\n\n```python\n main_realm = kc.admin()\n\n # Creates a realm called my_realm\n main_realm.create({"enabled": "true", "id": my_realm, "realm": my_realm})\n```\n\n\n### REST API\n\nWhen you use the ``build`` or ``admin`` methods you will get back a **REST** class pointing to the Keycloak resource, keep in mind that this class don\'t check that the resource is valid, this is done to keep it flexible and to make it easy to adapt to new Keycloak REST API changes in the future. \n\n#### Usage\n\nIn order to create one you need to ``build`` method we have used before:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nstate = users.create(batman).isOk()\n```\n\n#### Methods\n\nFollowing the example above lets see the methods we have starting with the usual CRUD methods:\n\n#### create\n\nThis method ``POST`` a dictionary into any given resource:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nstate = users.create(batman).isOk()\n```\n\n- **dictionary**: Dictionary with the fields we want to POST to the server.\n\n\n\n\n#### update\n\nThis method performs a ``PUT`` on the resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.update(id, batman_update).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n#### remove\nThis method sends a ``DELETE`` to the pointed resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.remove(id).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n\n#### get\nSend a ``GET`` request to retrieve a specific Keycloak resource.\n\n```python\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nuser = users.get(id).response()\n```\n\n#### all\n\nReturn all objects of a particular resource type.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nuser_list = users.all() #\xa0[ {id:\'xxx-yyy\', username: \'batman\', ...} ] \n```\n#### findFirst\nFinds a resource by passing an arbitrary key/value pair.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.findFirst({"key":"username", "value": \'batman\'})\n```\n\n#### exist\nCheck if a resource matching the provided ``id`` exists:\n```Python\nusers = kc.build(\'users\', \'DC\')\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nusers.exists(id) #True\n```\n\n#### existByKV\nCheck if a resource matching the provided key/value pair, exists.\n\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.existByKV("username", \'batman\') #False\n```\n\n\n### ResponseHandler\n\nEach **CRUD** method returns a ``ResponseHandler`` class with the following methods.\n\n#### Methods\n\n\n#### response\nreturns the requests [response object](https://docs.python-requests.org/en/latest/api/#requests.Response).\n\n```Python\nusers.update(id, batman_update).response().status_code #HTTP 201\n```\n\n\n#### isOk\n\nReturn ``True`` if the request complete successfully otherwise it will raise an exception.\n\n```Python\nstate = users.update(id, batman_update).isOk() # Return True here.\n```\n\n#### verify\n\nDoes the same as ``isOk`` but it allow you to chain more methods.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\ncookies = users.update(id, batman_update).verify().response().cookies # Get cookies.\n```\n\n\n## Specialisations\n\n### Realms \n\n### KeycloakCaches \n\nThis class handles the Keycloak caches. \n\n#### Instantiation \n\n```python\n# Creates a REST API instance target the Realms API. \nrealms = kc.build(\'realms\', \'my_realm\') \n\n# Gets the cache Realms cache API. \ncaches = realms.caches(self.REALM)\n```\n\n#### clearUserCache \nThis method tells Keycloak to clear the user cache.\n\n```python\ncaches.clearUserCache()\n```\n\n\n#### clearRealmCache \nThis method tells Keycloak to clear the realm cache.\n\n```python\ncaches.clearRealmCache()\n```\n\n\n#### clearKeyCache \nThis method tells Keycloak to clear the external public key cache for clients and identity providers.\n\n```python\ncaches.clearKeyCache()\n```\n\n> For more information on how this caches works follow this [link](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_installation_and_configuration_guide/server_cache_configuration).\n\n\n### Users\n\n#### updateCredentials\n\nUpdate user credentials.\n\n```js\nuser_credentials = {\n \'temporary\': False,\n \'value\':\'12345\'\n}\n\nstate = users.updateCredentials(user_info, user_credentials).isOk() # Updated user password.\n```\nWhere:\n- **temporary**: Boolean where if ``True`` provide a temporary password just for the first login. \n- **value**: String with the password.\n\n\n#### joinGroup\n\nAdd a user into a existing [group](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n\nFirst we need a group:\n```python\ndef createDCGroup():\n group = kc.build(\'groups\', \'heroes\')\n return group.create({"name": "DC"}).isOk()\n```\n\nThen we can join the group the following way:\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\n> The API works by matching the first occurrence between the provided ``key/value`` for the two resources (User and Group), this can help in various situation for example if we want to target the user by ``uuid``.\n\n\nUsing ``uuid`` as user identifier.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\nOr we want to use the group ``id``:\n\n```python\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "id", "value": "f8d91722-a1f0-45e..."}\n\n users.joinGroup(user, group).isOk()\n```\n> If the field criteria don\'t return a unique value, the first entry in the list will be used.\n#### leaveGroup\n\nRemove a user from a group.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "uuid", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n user = {"key": "uuid", "value": "12d3-a456-4"}\n group = {"key": "id", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n```\n\n> The same rules for ``key/value`` discussed above also applies here.\n\n\n### Groups\n\nTo manage the relationship between realm level [roles](keycloak.org/docs/latest/server_admin/#assigning-permissions-and-access-using-roles-and-groups) and groups, we can use the **RealmsRolesMapping**.\n\nTo get an instance of this class you need to instantiate the ``group`` resource class:\n\n```Python\ngroups = kc.build(\'groups\', \'heroes\')\n```\n\nAnd use the method ``realmRoles`` passing a valid [group dictionary](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_grouprepresentation):\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n```\n\nThen we get a class with following methods:\n\n#### add\n\nAdd a list of existing roles to a group.\n\n```python\ndef makeRoles(self):\n roles = kc.build(\'roles\', self.realm)\n lvl1 = roles.create({"name": "level-1"}).isOk()\n lvl2 = roles.create({"name": "level-2"}).isOk()\n return lvl1 and lvl2\n\n\nif makeRoles():\n realmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n realmsRoles.add(["level-1", "level-2"])\n```\n\n#### remove\nRemove a list of associated roles from a group.\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\nrealmsRoles.remove(["level-1", "level-2"])\n```\n\n\n## Roles \n\n\n#### composite\nIn Keycloak we can map roles to other roles, this method allow you to do just that. \n\n```python\nrole_watch = self.kc.build(\'roles\', \'my-realm\').find(\'watch\')\nadded = role_watch.add_composite(\'view\')\n```'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'readme' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'readme' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'license' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `license = 'MIT'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'license' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'license' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'dependencies' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `dependencies = ['requests']` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'dependencies' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'dependencies' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) HOOK STDOUT: running egg_info HOOK STDOUT: writing kcapi.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to kcapi.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to kcapi.egg-info/requires.txt HOOK STDOUT: writing top-level names to kcapi.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'kcapi.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'kcapi.egg-info/SOURCES.txt' Handling wheel from get_requires_for_build_wheel Requirement not satisfied: wheel Exiting dependency generation pass: get_requires_for_build_wheel + rm -rfv '*.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-kcapi-1.1.2-1.fc39.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1001gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', 'ba9edea47c954ccf8a1bb8ec65234788', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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', '--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', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1679961600 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.ontgCz + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf kcapi-1.1.2 + /usr/lib/rpm/rpmuncompress -x /builddir/build/SOURCES/kcapi-1.1.2.tar.gz + STATUS=0 + '[' 0 -ne 0 ']' + cd kcapi-1.1.2 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.cYaRu7 + umask 022 + cd /builddir/build/BUILD + cd kcapi-1.1.2 + 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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + echo '(python3dist(toml) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/kcapi-1.1.2/.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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + TMPDIR=/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir + RPM_TOXENV=py311 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/kcapi-1.1.2/pyproject-wheeldir Handling setuptools>=61.0 from build-system.requires Requirement satisfied: setuptools>=61.0 (installed: setuptools 67.6.1) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'readme' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `readme = '# Keycloak API\n\nPython module to automate Keycloak or Red Hat Single Sign-On (RHSSO) configuration.\n\n## How To Install\n\n```sh\npip install kcapi\n```\n\n\n## Testing\n\nTo run the test you would need a Keycloak instance, you can run one locally or in the [cloud]( https://developers.redhat.com/developer-sandbox/get-started) then you just have to follow this steps: \n\n```shell script\npython3.10 -m venv .venv\nsource .venv/bin/activate\npip install requests\n\n# Setup SSO server - go to https://developers.redhat.com/developer-sandbox/get-started,\n# launch sandbox environment, +Add, select some "Red Hat Single Sign-On..." template.\nexport KC_USER=admin\nexport KC_PASSWORD=admin_password\nexport KC_REALM=myrealm # do not use master realm, it cannot be removed\nexport KC_ENDPOINT=https://my-first-sso-me-me-dev.apps.sandbox.x8i5.p1.openshiftapps.com\n\npython -m unittest\n```\n\n\n## API\n\n### OpenID\n\nThis class takes care of OpenID login using [password owner credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3) flow.\n\n\n#### Constructor\n\n```python\nfrom rhsso import OpenID\n\noid_client = OpenID({\n "client_id": "admin-cli",\n "username": USER,\n "password": PASSWORD,\n "grant_type":"password",\n "realm" : "master"\n }, endpoint)\n```\n\n- **client_id**: Client Identifier in Keycloak.\n- **username**: Login username for the Realm.\n- **password**: Login password for the Realm.\n- **grant_type**: The grant type you want to use (usually ``password``).\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n##### getToken\n\nThis will initiate a session with the Keycloak server and will return a OpenID token back.\n\n```python\noid_client.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n\n##### createAdminClient\n\nThis static method should be used in order to access the master Realm in Keycloak.\n\n```python\n oidc = OpenID.createAdminClient(self.USER, self.PASSWORD)\n oidc.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n### Keycloak\n\nThis class builds all the Keycloak configuration REST resources by using REST conventions we can target the majority of Keycloak services.\n\n#### Constructor\n\n```Python\nkc = Keycloak(token, self.ENDPOINT)\n```\n\nThe constructor takes two parameters:\n\n- **token**: A token with enough priviledge to perform the desired operation.\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n#### build\nThis methods build a REST client (capabilities detailed below) targeting a specific Keycloak REST resource.\n\n```python\ngroups = kc.build(\'groups\', \'my_realm\')\n\n# Create a group called DC\nstate = groups.create({"name": "DC"}).isOk()\n\n```\n> In this example we build the \'groups\' API for ``my_realm`` Realm.\n\n##### Supported Resources\n\nHere is a quick list of supported resources:\n\n- **users**: [users API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_user).\n- **clients**: [client API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_client). \n- **groups**: [groups API](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n- **roles**: [roles API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_role_for_the_realm_or_client_2)\n- **identity-provider**: [identity provider API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_get_identity_providers)\n\n\n> As long as you find a REST endpoint that follow the standard you can use this method to build a client around it, an example of this is the non well documented ``components`` endpoint.\n\n- **components**: This API allows you configure things like [user federation](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/user-storage-federation) or [Realm keys](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/admin_permissions#realm_keys).\n\n- **authentication**: Provide access to built-in and/or custom authentication flows.\n
\n\n#### admin\nSimilar to the ``build`` method but the client points to the ``master`` realm, allowing us operation such as realm creation.\n\n```python\n main_realm = kc.admin()\n\n # Creates a realm called my_realm\n main_realm.create({"enabled": "true", "id": my_realm, "realm": my_realm})\n```\n\n\n### REST API\n\nWhen you use the ``build`` or ``admin`` methods you will get back a **REST** class pointing to the Keycloak resource, keep in mind that this class don\'t check that the resource is valid, this is done to keep it flexible and to make it easy to adapt to new Keycloak REST API changes in the future. \n\n#### Usage\n\nIn order to create one you need to ``build`` method we have used before:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nstate = users.create(batman).isOk()\n```\n\n#### Methods\n\nFollowing the example above lets see the methods we have starting with the usual CRUD methods:\n\n#### create\n\nThis method ``POST`` a dictionary into any given resource:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nstate = users.create(batman).isOk()\n```\n\n- **dictionary**: Dictionary with the fields we want to POST to the server.\n\n\n\n\n#### update\n\nThis method performs a ``PUT`` on the resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.update(id, batman_update).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n#### remove\nThis method sends a ``DELETE`` to the pointed resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.remove(id).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n\n#### get\nSend a ``GET`` request to retrieve a specific Keycloak resource.\n\n```python\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nuser = users.get(id).response()\n```\n\n#### all\n\nReturn all objects of a particular resource type.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nuser_list = users.all() #\xa0[ {id:\'xxx-yyy\', username: \'batman\', ...} ] \n```\n#### findFirst\nFinds a resource by passing an arbitrary key/value pair.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.findFirst({"key":"username", "value": \'batman\'})\n```\n\n#### exist\nCheck if a resource matching the provided ``id`` exists:\n```Python\nusers = kc.build(\'users\', \'DC\')\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nusers.exists(id) #True\n```\n\n#### existByKV\nCheck if a resource matching the provided key/value pair, exists.\n\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.existByKV("username", \'batman\') #False\n```\n\n\n### ResponseHandler\n\nEach **CRUD** method returns a ``ResponseHandler`` class with the following methods.\n\n#### Methods\n\n\n#### response\nreturns the requests [response object](https://docs.python-requests.org/en/latest/api/#requests.Response).\n\n```Python\nusers.update(id, batman_update).response().status_code #HTTP 201\n```\n\n\n#### isOk\n\nReturn ``True`` if the request complete successfully otherwise it will raise an exception.\n\n```Python\nstate = users.update(id, batman_update).isOk() # Return True here.\n```\n\n#### verify\n\nDoes the same as ``isOk`` but it allow you to chain more methods.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\ncookies = users.update(id, batman_update).verify().response().cookies # Get cookies.\n```\n\n\n## Specialisations\n\n### Realms \n\n### KeycloakCaches \n\nThis class handles the Keycloak caches. \n\n#### Instantiation \n\n```python\n# Creates a REST API instance target the Realms API. \nrealms = kc.build(\'realms\', \'my_realm\') \n\n# Gets the cache Realms cache API. \ncaches = realms.caches(self.REALM)\n```\n\n#### clearUserCache \nThis method tells Keycloak to clear the user cache.\n\n```python\ncaches.clearUserCache()\n```\n\n\n#### clearRealmCache \nThis method tells Keycloak to clear the realm cache.\n\n```python\ncaches.clearRealmCache()\n```\n\n\n#### clearKeyCache \nThis method tells Keycloak to clear the external public key cache for clients and identity providers.\n\n```python\ncaches.clearKeyCache()\n```\n\n> For more information on how this caches works follow this [link](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_installation_and_configuration_guide/server_cache_configuration).\n\n\n### Users\n\n#### updateCredentials\n\nUpdate user credentials.\n\n```js\nuser_credentials = {\n \'temporary\': False,\n \'value\':\'12345\'\n}\n\nstate = users.updateCredentials(user_info, user_credentials).isOk() # Updated user password.\n```\nWhere:\n- **temporary**: Boolean where if ``True`` provide a temporary password just for the first login. \n- **value**: String with the password.\n\n\n#### joinGroup\n\nAdd a user into a existing [group](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n\nFirst we need a group:\n```python\ndef createDCGroup():\n group = kc.build(\'groups\', \'heroes\')\n return group.create({"name": "DC"}).isOk()\n```\n\nThen we can join the group the following way:\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\n> The API works by matching the first occurrence between the provided ``key/value`` for the two resources (User and Group), this can help in various situation for example if we want to target the user by ``uuid``.\n\n\nUsing ``uuid`` as user identifier.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\nOr we want to use the group ``id``:\n\n```python\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "id", "value": "f8d91722-a1f0-45e..."}\n\n users.joinGroup(user, group).isOk()\n```\n> If the field criteria don\'t return a unique value, the first entry in the list will be used.\n#### leaveGroup\n\nRemove a user from a group.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "uuid", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n user = {"key": "uuid", "value": "12d3-a456-4"}\n group = {"key": "id", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n```\n\n> The same rules for ``key/value`` discussed above also applies here.\n\n\n### Groups\n\nTo manage the relationship between realm level [roles](keycloak.org/docs/latest/server_admin/#assigning-permissions-and-access-using-roles-and-groups) and groups, we can use the **RealmsRolesMapping**.\n\nTo get an instance of this class you need to instantiate the ``group`` resource class:\n\n```Python\ngroups = kc.build(\'groups\', \'heroes\')\n```\n\nAnd use the method ``realmRoles`` passing a valid [group dictionary](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_grouprepresentation):\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n```\n\nThen we get a class with following methods:\n\n#### add\n\nAdd a list of existing roles to a group.\n\n```python\ndef makeRoles(self):\n roles = kc.build(\'roles\', self.realm)\n lvl1 = roles.create({"name": "level-1"}).isOk()\n lvl2 = roles.create({"name": "level-2"}).isOk()\n return lvl1 and lvl2\n\n\nif makeRoles():\n realmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n realmsRoles.add(["level-1", "level-2"])\n```\n\n#### remove\nRemove a list of associated roles from a group.\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\nrealmsRoles.remove(["level-1", "level-2"])\n```\n\n\n## Roles \n\n\n#### composite\nIn Keycloak we can map roles to other roles, this method allow you to do just that. \n\n```python\nrole_watch = self.kc.build(\'roles\', \'my-realm\').find(\'watch\')\nadded = role_watch.add_composite(\'view\')\n```'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'readme' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'readme' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'license' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `license = 'MIT'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'license' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'license' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'dependencies' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `dependencies = ['requests']` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'dependencies' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'dependencies' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) HOOK STDOUT: running egg_info HOOK STDOUT: writing kcapi.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to kcapi.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to kcapi.egg-info/requires.txt HOOK STDOUT: writing top-level names to kcapi.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'kcapi.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'kcapi.egg-info/SOURCES.txt' Handling wheel from get_requires_for_build_wheel Requirement satisfied: wheel (installed: wheel 0.38.4) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'readme' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `readme = '# Keycloak API\n\nPython module to automate Keycloak or Red Hat Single Sign-On (RHSSO) configuration.\n\n## How To Install\n\n```sh\npip install kcapi\n```\n\n\n## Testing\n\nTo run the test you would need a Keycloak instance, you can run one locally or in the [cloud]( https://developers.redhat.com/developer-sandbox/get-started) then you just have to follow this steps: \n\n```shell script\npython3.10 -m venv .venv\nsource .venv/bin/activate\npip install requests\n\n# Setup SSO server - go to https://developers.redhat.com/developer-sandbox/get-started,\n# launch sandbox environment, +Add, select some "Red Hat Single Sign-On..." template.\nexport KC_USER=admin\nexport KC_PASSWORD=admin_password\nexport KC_REALM=myrealm # do not use master realm, it cannot be removed\nexport KC_ENDPOINT=https://my-first-sso-me-me-dev.apps.sandbox.x8i5.p1.openshiftapps.com\n\npython -m unittest\n```\n\n\n## API\n\n### OpenID\n\nThis class takes care of OpenID login using [password owner credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3) flow.\n\n\n#### Constructor\n\n```python\nfrom rhsso import OpenID\n\noid_client = OpenID({\n "client_id": "admin-cli",\n "username": USER,\n "password": PASSWORD,\n "grant_type":"password",\n "realm" : "master"\n }, endpoint)\n```\n\n- **client_id**: Client Identifier in Keycloak.\n- **username**: Login username for the Realm.\n- **password**: Login password for the Realm.\n- **grant_type**: The grant type you want to use (usually ``password``).\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n##### getToken\n\nThis will initiate a session with the Keycloak server and will return a OpenID token back.\n\n```python\noid_client.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n\n##### createAdminClient\n\nThis static method should be used in order to access the master Realm in Keycloak.\n\n```python\n oidc = OpenID.createAdminClient(self.USER, self.PASSWORD)\n oidc.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n### Keycloak\n\nThis class builds all the Keycloak configuration REST resources by using REST conventions we can target the majority of Keycloak services.\n\n#### Constructor\n\n```Python\nkc = Keycloak(token, self.ENDPOINT)\n```\n\nThe constructor takes two parameters:\n\n- **token**: A token with enough priviledge to perform the desired operation.\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n#### build\nThis methods build a REST client (capabilities detailed below) targeting a specific Keycloak REST resource.\n\n```python\ngroups = kc.build(\'groups\', \'my_realm\')\n\n# Create a group called DC\nstate = groups.create({"name": "DC"}).isOk()\n\n```\n> In this example we build the \'groups\' API for ``my_realm`` Realm.\n\n##### Supported Resources\n\nHere is a quick list of supported resources:\n\n- **users**: [users API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_user).\n- **clients**: [client API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_client). \n- **groups**: [groups API](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n- **roles**: [roles API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_role_for_the_realm_or_client_2)\n- **identity-provider**: [identity provider API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_get_identity_providers)\n\n\n> As long as you find a REST endpoint that follow the standard you can use this method to build a client around it, an example of this is the non well documented ``components`` endpoint.\n\n- **components**: This API allows you configure things like [user federation](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/user-storage-federation) or [Realm keys](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/admin_permissions#realm_keys).\n\n- **authentication**: Provide access to built-in and/or custom authentication flows.\n
\n\n#### admin\nSimilar to the ``build`` method but the client points to the ``master`` realm, allowing us operation such as realm creation.\n\n```python\n main_realm = kc.admin()\n\n # Creates a realm called my_realm\n main_realm.create({"enabled": "true", "id": my_realm, "realm": my_realm})\n```\n\n\n### REST API\n\nWhen you use the ``build`` or ``admin`` methods you will get back a **REST** class pointing to the Keycloak resource, keep in mind that this class don\'t check that the resource is valid, this is done to keep it flexible and to make it easy to adapt to new Keycloak REST API changes in the future. \n\n#### Usage\n\nIn order to create one you need to ``build`` method we have used before:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nstate = users.create(batman).isOk()\n```\n\n#### Methods\n\nFollowing the example above lets see the methods we have starting with the usual CRUD methods:\n\n#### create\n\nThis method ``POST`` a dictionary into any given resource:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nstate = users.create(batman).isOk()\n```\n\n- **dictionary**: Dictionary with the fields we want to POST to the server.\n\n\n\n\n#### update\n\nThis method performs a ``PUT`` on the resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.update(id, batman_update).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n#### remove\nThis method sends a ``DELETE`` to the pointed resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.remove(id).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n\n#### get\nSend a ``GET`` request to retrieve a specific Keycloak resource.\n\n```python\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nuser = users.get(id).response()\n```\n\n#### all\n\nReturn all objects of a particular resource type.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nuser_list = users.all() #\xa0[ {id:\'xxx-yyy\', username: \'batman\', ...} ] \n```\n#### findFirst\nFinds a resource by passing an arbitrary key/value pair.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.findFirst({"key":"username", "value": \'batman\'})\n```\n\n#### exist\nCheck if a resource matching the provided ``id`` exists:\n```Python\nusers = kc.build(\'users\', \'DC\')\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nusers.exists(id) #True\n```\n\n#### existByKV\nCheck if a resource matching the provided key/value pair, exists.\n\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.existByKV("username", \'batman\') #False\n```\n\n\n### ResponseHandler\n\nEach **CRUD** method returns a ``ResponseHandler`` class with the following methods.\n\n#### Methods\n\n\n#### response\nreturns the requests [response object](https://docs.python-requests.org/en/latest/api/#requests.Response).\n\n```Python\nusers.update(id, batman_update).response().status_code #HTTP 201\n```\n\n\n#### isOk\n\nReturn ``True`` if the request complete successfully otherwise it will raise an exception.\n\n```Python\nstate = users.update(id, batman_update).isOk() # Return True here.\n```\n\n#### verify\n\nDoes the same as ``isOk`` but it allow you to chain more methods.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\ncookies = users.update(id, batman_update).verify().response().cookies # Get cookies.\n```\n\n\n## Specialisations\n\n### Realms \n\n### KeycloakCaches \n\nThis class handles the Keycloak caches. \n\n#### Instantiation \n\n```python\n# Creates a REST API instance target the Realms API. \nrealms = kc.build(\'realms\', \'my_realm\') \n\n# Gets the cache Realms cache API. \ncaches = realms.caches(self.REALM)\n```\n\n#### clearUserCache \nThis method tells Keycloak to clear the user cache.\n\n```python\ncaches.clearUserCache()\n```\n\n\n#### clearRealmCache \nThis method tells Keycloak to clear the realm cache.\n\n```python\ncaches.clearRealmCache()\n```\n\n\n#### clearKeyCache \nThis method tells Keycloak to clear the external public key cache for clients and identity providers.\n\n```python\ncaches.clearKeyCache()\n```\n\n> For more information on how this caches works follow this [link](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_installation_and_configuration_guide/server_cache_configuration).\n\n\n### Users\n\n#### updateCredentials\n\nUpdate user credentials.\n\n```js\nuser_credentials = {\n \'temporary\': False,\n \'value\':\'12345\'\n}\n\nstate = users.updateCredentials(user_info, user_credentials).isOk() # Updated user password.\n```\nWhere:\n- **temporary**: Boolean where if ``True`` provide a temporary password just for the first login. \n- **value**: String with the password.\n\n\n#### joinGroup\n\nAdd a user into a existing [group](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n\nFirst we need a group:\n```python\ndef createDCGroup():\n group = kc.build(\'groups\', \'heroes\')\n return group.create({"name": "DC"}).isOk()\n```\n\nThen we can join the group the following way:\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\n> The API works by matching the first occurrence between the provided ``key/value`` for the two resources (User and Group), this can help in various situation for example if we want to target the user by ``uuid``.\n\n\nUsing ``uuid`` as user identifier.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\nOr we want to use the group ``id``:\n\n```python\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "id", "value": "f8d91722-a1f0-45e..."}\n\n users.joinGroup(user, group).isOk()\n```\n> If the field criteria don\'t return a unique value, the first entry in the list will be used.\n#### leaveGroup\n\nRemove a user from a group.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "uuid", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n user = {"key": "uuid", "value": "12d3-a456-4"}\n group = {"key": "id", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n```\n\n> The same rules for ``key/value`` discussed above also applies here.\n\n\n### Groups\n\nTo manage the relationship between realm level [roles](keycloak.org/docs/latest/server_admin/#assigning-permissions-and-access-using-roles-and-groups) and groups, we can use the **RealmsRolesMapping**.\n\nTo get an instance of this class you need to instantiate the ``group`` resource class:\n\n```Python\ngroups = kc.build(\'groups\', \'heroes\')\n```\n\nAnd use the method ``realmRoles`` passing a valid [group dictionary](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_grouprepresentation):\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n```\n\nThen we get a class with following methods:\n\n#### add\n\nAdd a list of existing roles to a group.\n\n```python\ndef makeRoles(self):\n roles = kc.build(\'roles\', self.realm)\n lvl1 = roles.create({"name": "level-1"}).isOk()\n lvl2 = roles.create({"name": "level-2"}).isOk()\n return lvl1 and lvl2\n\n\nif makeRoles():\n realmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n realmsRoles.add(["level-1", "level-2"])\n```\n\n#### remove\nRemove a list of associated roles from a group.\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\nrealmsRoles.remove(["level-1", "level-2"])\n```\n\n\n## Roles \n\n\n#### composite\nIn Keycloak we can map roles to other roles, this method allow you to do just that. \n\n```python\nrole_watch = self.kc.build(\'roles\', \'my-realm\').find(\'watch\')\nadded = role_watch.add_composite(\'view\')\n```'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'readme' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'readme' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'license' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `license = 'MIT'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'license' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'license' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'dependencies' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `dependencies = ['requests']` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'dependencies' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'dependencies' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 985, in run_command log.info("running %s", command) Message: 'running %s' Arguments: ('dist_info',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 684, in write_pkg_info log.info("writing %s", filename) Message: 'writing %s' Arguments: ('kcapi.egg-info/PKG-INFO',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 747, in overwrite_arg write_arg(cmd, basename, filename, True) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 755, in write_arg cmd.write_or_delete_file(argname, filename, value, force) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 273, in write_or_delete_file self.write_file(what, filename, data) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 289, in write_file log.info("writing %s to %s", what, filename) Message: 'writing %s to %s' Arguments: ('dependency_links', 'kcapi.egg-info/dependency_links.txt') --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 727, in write_requirements cmd.write_or_delete_file("requirements", filename, data.getvalue()) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 273, in write_or_delete_file self.write_file(what, filename, data) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 289, in write_file log.info("writing %s to %s", what, filename) Message: 'writing %s to %s' Arguments: ('requirements', 'kcapi.egg-info/requires.txt') --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 743, in write_toplevel_names cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n') File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 289, in write_file log.info("writing %s to %s", what, filename) Message: 'writing %s to %s' Arguments: ('top-level names', 'kcapi.egg-info/top_level.txt') --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 318, in run self.find_sources() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 326, in find_sources mm.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 570, in run self.add_defaults() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 615, in add_defaults self.read_manifest() File "/usr/lib/python3.11/site-packages/setuptools/command/sdist.py", line 196, in read_manifest log.info("reading manifest file '%s'", self.manifest) Message: "reading manifest file '%s'" Arguments: ('kcapi.egg-info/SOURCES.txt',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 318, in run self.find_sources() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 326, in find_sources mm.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 573, in run self.add_license_files() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 628, in add_license_files log.info("adding license file '%s'", lf) Message: "adding license file '%s'" Arguments: ('LICENSE',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 318, in run self.find_sources() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 326, in find_sources mm.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 578, in run self.write_manifest() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 594, in write_manifest self.execute(write_file, (self.manifest, files), msg) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/cmd.py", line 339, in execute util.execute(func, args, msg, dry_run=self.dry_run) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/util.py", line 335, in execute log.info(msg) Message: "writing manifest file 'kcapi.egg-info/SOURCES.txt'" Arguments: () --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 102, in run log.info("creating '{}'".format(os.path.abspath(self.dist_info_dir))) Message: "creating '/builddir/build/BUILD/kcapi-1.1.2/kcapi-1.1.2.dist-info'" Arguments: () Handling requests from hook generated metadata: Requires-Dist Requirement not satisfied: requests + rm -rfv kcapi-1.1.2.dist-info/ removed 'kcapi-1.1.2.dist-info/LICENSE' removed 'kcapi-1.1.2.dist-info/METADATA' removed 'kcapi-1.1.2.dist-info/top_level.txt' removed directory 'kcapi-1.1.2.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-kcapi-1.1.2-1.fc39.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1001gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', '946dc6a4f81a4ca1a7b853fd63135916', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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', '--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', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1679961600 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.ZOesqp + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf kcapi-1.1.2 + /usr/lib/rpm/rpmuncompress -x /builddir/build/SOURCES/kcapi-1.1.2.tar.gz + STATUS=0 + '[' 0 -ne 0 ']' + cd kcapi-1.1.2 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.X3Kc3f + umask 022 + cd /builddir/build/BUILD + cd kcapi-1.1.2 + 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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + echo '(python3dist(toml) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/kcapi-1.1.2/.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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + TMPDIR=/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir + RPM_TOXENV=py311 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/kcapi-1.1.2/pyproject-wheeldir Handling setuptools>=61.0 from build-system.requires Requirement satisfied: setuptools>=61.0 (installed: setuptools 67.6.1) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'readme' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `readme = '# Keycloak API\n\nPython module to automate Keycloak or Red Hat Single Sign-On (RHSSO) configuration.\n\n## How To Install\n\n```sh\npip install kcapi\n```\n\n\n## Testing\n\nTo run the test you would need a Keycloak instance, you can run one locally or in the [cloud]( https://developers.redhat.com/developer-sandbox/get-started) then you just have to follow this steps: \n\n```shell script\npython3.10 -m venv .venv\nsource .venv/bin/activate\npip install requests\n\n# Setup SSO server - go to https://developers.redhat.com/developer-sandbox/get-started,\n# launch sandbox environment, +Add, select some "Red Hat Single Sign-On..." template.\nexport KC_USER=admin\nexport KC_PASSWORD=admin_password\nexport KC_REALM=myrealm # do not use master realm, it cannot be removed\nexport KC_ENDPOINT=https://my-first-sso-me-me-dev.apps.sandbox.x8i5.p1.openshiftapps.com\n\npython -m unittest\n```\n\n\n## API\n\n### OpenID\n\nThis class takes care of OpenID login using [password owner credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3) flow.\n\n\n#### Constructor\n\n```python\nfrom rhsso import OpenID\n\noid_client = OpenID({\n "client_id": "admin-cli",\n "username": USER,\n "password": PASSWORD,\n "grant_type":"password",\n "realm" : "master"\n }, endpoint)\n```\n\n- **client_id**: Client Identifier in Keycloak.\n- **username**: Login username for the Realm.\n- **password**: Login password for the Realm.\n- **grant_type**: The grant type you want to use (usually ``password``).\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n##### getToken\n\nThis will initiate a session with the Keycloak server and will return a OpenID token back.\n\n```python\noid_client.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n\n##### createAdminClient\n\nThis static method should be used in order to access the master Realm in Keycloak.\n\n```python\n oidc = OpenID.createAdminClient(self.USER, self.PASSWORD)\n oidc.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n### Keycloak\n\nThis class builds all the Keycloak configuration REST resources by using REST conventions we can target the majority of Keycloak services.\n\n#### Constructor\n\n```Python\nkc = Keycloak(token, self.ENDPOINT)\n```\n\nThe constructor takes two parameters:\n\n- **token**: A token with enough priviledge to perform the desired operation.\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n#### build\nThis methods build a REST client (capabilities detailed below) targeting a specific Keycloak REST resource.\n\n```python\ngroups = kc.build(\'groups\', \'my_realm\')\n\n# Create a group called DC\nstate = groups.create({"name": "DC"}).isOk()\n\n```\n> In this example we build the \'groups\' API for ``my_realm`` Realm.\n\n##### Supported Resources\n\nHere is a quick list of supported resources:\n\n- **users**: [users API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_user).\n- **clients**: [client API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_client). \n- **groups**: [groups API](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n- **roles**: [roles API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_role_for_the_realm_or_client_2)\n- **identity-provider**: [identity provider API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_get_identity_providers)\n\n\n> As long as you find a REST endpoint that follow the standard you can use this method to build a client around it, an example of this is the non well documented ``components`` endpoint.\n\n- **components**: This API allows you configure things like [user federation](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/user-storage-federation) or [Realm keys](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/admin_permissions#realm_keys).\n\n- **authentication**: Provide access to built-in and/or custom authentication flows.\n
\n\n#### admin\nSimilar to the ``build`` method but the client points to the ``master`` realm, allowing us operation such as realm creation.\n\n```python\n main_realm = kc.admin()\n\n # Creates a realm called my_realm\n main_realm.create({"enabled": "true", "id": my_realm, "realm": my_realm})\n```\n\n\n### REST API\n\nWhen you use the ``build`` or ``admin`` methods you will get back a **REST** class pointing to the Keycloak resource, keep in mind that this class don\'t check that the resource is valid, this is done to keep it flexible and to make it easy to adapt to new Keycloak REST API changes in the future. \n\n#### Usage\n\nIn order to create one you need to ``build`` method we have used before:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nstate = users.create(batman).isOk()\n```\n\n#### Methods\n\nFollowing the example above lets see the methods we have starting with the usual CRUD methods:\n\n#### create\n\nThis method ``POST`` a dictionary into any given resource:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nstate = users.create(batman).isOk()\n```\n\n- **dictionary**: Dictionary with the fields we want to POST to the server.\n\n\n\n\n#### update\n\nThis method performs a ``PUT`` on the resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.update(id, batman_update).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n#### remove\nThis method sends a ``DELETE`` to the pointed resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.remove(id).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n\n#### get\nSend a ``GET`` request to retrieve a specific Keycloak resource.\n\n```python\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nuser = users.get(id).response()\n```\n\n#### all\n\nReturn all objects of a particular resource type.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nuser_list = users.all() #\xa0[ {id:\'xxx-yyy\', username: \'batman\', ...} ] \n```\n#### findFirst\nFinds a resource by passing an arbitrary key/value pair.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.findFirst({"key":"username", "value": \'batman\'})\n```\n\n#### exist\nCheck if a resource matching the provided ``id`` exists:\n```Python\nusers = kc.build(\'users\', \'DC\')\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nusers.exists(id) #True\n```\n\n#### existByKV\nCheck if a resource matching the provided key/value pair, exists.\n\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.existByKV("username", \'batman\') #False\n```\n\n\n### ResponseHandler\n\nEach **CRUD** method returns a ``ResponseHandler`` class with the following methods.\n\n#### Methods\n\n\n#### response\nreturns the requests [response object](https://docs.python-requests.org/en/latest/api/#requests.Response).\n\n```Python\nusers.update(id, batman_update).response().status_code #HTTP 201\n```\n\n\n#### isOk\n\nReturn ``True`` if the request complete successfully otherwise it will raise an exception.\n\n```Python\nstate = users.update(id, batman_update).isOk() # Return True here.\n```\n\n#### verify\n\nDoes the same as ``isOk`` but it allow you to chain more methods.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\ncookies = users.update(id, batman_update).verify().response().cookies # Get cookies.\n```\n\n\n## Specialisations\n\n### Realms \n\n### KeycloakCaches \n\nThis class handles the Keycloak caches. \n\n#### Instantiation \n\n```python\n# Creates a REST API instance target the Realms API. \nrealms = kc.build(\'realms\', \'my_realm\') \n\n# Gets the cache Realms cache API. \ncaches = realms.caches(self.REALM)\n```\n\n#### clearUserCache \nThis method tells Keycloak to clear the user cache.\n\n```python\ncaches.clearUserCache()\n```\n\n\n#### clearRealmCache \nThis method tells Keycloak to clear the realm cache.\n\n```python\ncaches.clearRealmCache()\n```\n\n\n#### clearKeyCache \nThis method tells Keycloak to clear the external public key cache for clients and identity providers.\n\n```python\ncaches.clearKeyCache()\n```\n\n> For more information on how this caches works follow this [link](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_installation_and_configuration_guide/server_cache_configuration).\n\n\n### Users\n\n#### updateCredentials\n\nUpdate user credentials.\n\n```js\nuser_credentials = {\n \'temporary\': False,\n \'value\':\'12345\'\n}\n\nstate = users.updateCredentials(user_info, user_credentials).isOk() # Updated user password.\n```\nWhere:\n- **temporary**: Boolean where if ``True`` provide a temporary password just for the first login. \n- **value**: String with the password.\n\n\n#### joinGroup\n\nAdd a user into a existing [group](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n\nFirst we need a group:\n```python\ndef createDCGroup():\n group = kc.build(\'groups\', \'heroes\')\n return group.create({"name": "DC"}).isOk()\n```\n\nThen we can join the group the following way:\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\n> The API works by matching the first occurrence between the provided ``key/value`` for the two resources (User and Group), this can help in various situation for example if we want to target the user by ``uuid``.\n\n\nUsing ``uuid`` as user identifier.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\nOr we want to use the group ``id``:\n\n```python\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "id", "value": "f8d91722-a1f0-45e..."}\n\n users.joinGroup(user, group).isOk()\n```\n> If the field criteria don\'t return a unique value, the first entry in the list will be used.\n#### leaveGroup\n\nRemove a user from a group.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "uuid", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n user = {"key": "uuid", "value": "12d3-a456-4"}\n group = {"key": "id", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n```\n\n> The same rules for ``key/value`` discussed above also applies here.\n\n\n### Groups\n\nTo manage the relationship between realm level [roles](keycloak.org/docs/latest/server_admin/#assigning-permissions-and-access-using-roles-and-groups) and groups, we can use the **RealmsRolesMapping**.\n\nTo get an instance of this class you need to instantiate the ``group`` resource class:\n\n```Python\ngroups = kc.build(\'groups\', \'heroes\')\n```\n\nAnd use the method ``realmRoles`` passing a valid [group dictionary](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_grouprepresentation):\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n```\n\nThen we get a class with following methods:\n\n#### add\n\nAdd a list of existing roles to a group.\n\n```python\ndef makeRoles(self):\n roles = kc.build(\'roles\', self.realm)\n lvl1 = roles.create({"name": "level-1"}).isOk()\n lvl2 = roles.create({"name": "level-2"}).isOk()\n return lvl1 and lvl2\n\n\nif makeRoles():\n realmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n realmsRoles.add(["level-1", "level-2"])\n```\n\n#### remove\nRemove a list of associated roles from a group.\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\nrealmsRoles.remove(["level-1", "level-2"])\n```\n\n\n## Roles \n\n\n#### composite\nIn Keycloak we can map roles to other roles, this method allow you to do just that. \n\n```python\nrole_watch = self.kc.build(\'roles\', \'my-realm\').find(\'watch\')\nadded = role_watch.add_composite(\'view\')\n```'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'readme' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'readme' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'license' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `license = 'MIT'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'license' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'license' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'dependencies' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `dependencies = ['requests']` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'dependencies' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'dependencies' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) HOOK STDOUT: running egg_info HOOK STDOUT: writing kcapi.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to kcapi.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to kcapi.egg-info/requires.txt HOOK STDOUT: writing top-level names to kcapi.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'kcapi.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'kcapi.egg-info/SOURCES.txt' Handling wheel from get_requires_for_build_wheel Requirement satisfied: wheel (installed: wheel 0.38.4) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'readme' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `readme = '# Keycloak API\n\nPython module to automate Keycloak or Red Hat Single Sign-On (RHSSO) configuration.\n\n## How To Install\n\n```sh\npip install kcapi\n```\n\n\n## Testing\n\nTo run the test you would need a Keycloak instance, you can run one locally or in the [cloud]( https://developers.redhat.com/developer-sandbox/get-started) then you just have to follow this steps: \n\n```shell script\npython3.10 -m venv .venv\nsource .venv/bin/activate\npip install requests\n\n# Setup SSO server - go to https://developers.redhat.com/developer-sandbox/get-started,\n# launch sandbox environment, +Add, select some "Red Hat Single Sign-On..." template.\nexport KC_USER=admin\nexport KC_PASSWORD=admin_password\nexport KC_REALM=myrealm # do not use master realm, it cannot be removed\nexport KC_ENDPOINT=https://my-first-sso-me-me-dev.apps.sandbox.x8i5.p1.openshiftapps.com\n\npython -m unittest\n```\n\n\n## API\n\n### OpenID\n\nThis class takes care of OpenID login using [password owner credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3) flow.\n\n\n#### Constructor\n\n```python\nfrom rhsso import OpenID\n\noid_client = OpenID({\n "client_id": "admin-cli",\n "username": USER,\n "password": PASSWORD,\n "grant_type":"password",\n "realm" : "master"\n }, endpoint)\n```\n\n- **client_id**: Client Identifier in Keycloak.\n- **username**: Login username for the Realm.\n- **password**: Login password for the Realm.\n- **grant_type**: The grant type you want to use (usually ``password``).\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n##### getToken\n\nThis will initiate a session with the Keycloak server and will return a OpenID token back.\n\n```python\noid_client.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n\n##### createAdminClient\n\nThis static method should be used in order to access the master Realm in Keycloak.\n\n```python\n oidc = OpenID.createAdminClient(self.USER, self.PASSWORD)\n oidc.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n### Keycloak\n\nThis class builds all the Keycloak configuration REST resources by using REST conventions we can target the majority of Keycloak services.\n\n#### Constructor\n\n```Python\nkc = Keycloak(token, self.ENDPOINT)\n```\n\nThe constructor takes two parameters:\n\n- **token**: A token with enough priviledge to perform the desired operation.\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n#### build\nThis methods build a REST client (capabilities detailed below) targeting a specific Keycloak REST resource.\n\n```python\ngroups = kc.build(\'groups\', \'my_realm\')\n\n# Create a group called DC\nstate = groups.create({"name": "DC"}).isOk()\n\n```\n> In this example we build the \'groups\' API for ``my_realm`` Realm.\n\n##### Supported Resources\n\nHere is a quick list of supported resources:\n\n- **users**: [users API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_user).\n- **clients**: [client API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_client). \n- **groups**: [groups API](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n- **roles**: [roles API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_role_for_the_realm_or_client_2)\n- **identity-provider**: [identity provider API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_get_identity_providers)\n\n\n> As long as you find a REST endpoint that follow the standard you can use this method to build a client around it, an example of this is the non well documented ``components`` endpoint.\n\n- **components**: This API allows you configure things like [user federation](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/user-storage-federation) or [Realm keys](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/admin_permissions#realm_keys).\n\n- **authentication**: Provide access to built-in and/or custom authentication flows.\n
\n\n#### admin\nSimilar to the ``build`` method but the client points to the ``master`` realm, allowing us operation such as realm creation.\n\n```python\n main_realm = kc.admin()\n\n # Creates a realm called my_realm\n main_realm.create({"enabled": "true", "id": my_realm, "realm": my_realm})\n```\n\n\n### REST API\n\nWhen you use the ``build`` or ``admin`` methods you will get back a **REST** class pointing to the Keycloak resource, keep in mind that this class don\'t check that the resource is valid, this is done to keep it flexible and to make it easy to adapt to new Keycloak REST API changes in the future. \n\n#### Usage\n\nIn order to create one you need to ``build`` method we have used before:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nstate = users.create(batman).isOk()\n```\n\n#### Methods\n\nFollowing the example above lets see the methods we have starting with the usual CRUD methods:\n\n#### create\n\nThis method ``POST`` a dictionary into any given resource:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nstate = users.create(batman).isOk()\n```\n\n- **dictionary**: Dictionary with the fields we want to POST to the server.\n\n\n\n\n#### update\n\nThis method performs a ``PUT`` on the resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.update(id, batman_update).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n#### remove\nThis method sends a ``DELETE`` to the pointed resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.remove(id).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n\n#### get\nSend a ``GET`` request to retrieve a specific Keycloak resource.\n\n```python\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nuser = users.get(id).response()\n```\n\n#### all\n\nReturn all objects of a particular resource type.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nuser_list = users.all() #\xa0[ {id:\'xxx-yyy\', username: \'batman\', ...} ] \n```\n#### findFirst\nFinds a resource by passing an arbitrary key/value pair.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.findFirst({"key":"username", "value": \'batman\'})\n```\n\n#### exist\nCheck if a resource matching the provided ``id`` exists:\n```Python\nusers = kc.build(\'users\', \'DC\')\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nusers.exists(id) #True\n```\n\n#### existByKV\nCheck if a resource matching the provided key/value pair, exists.\n\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.existByKV("username", \'batman\') #False\n```\n\n\n### ResponseHandler\n\nEach **CRUD** method returns a ``ResponseHandler`` class with the following methods.\n\n#### Methods\n\n\n#### response\nreturns the requests [response object](https://docs.python-requests.org/en/latest/api/#requests.Response).\n\n```Python\nusers.update(id, batman_update).response().status_code #HTTP 201\n```\n\n\n#### isOk\n\nReturn ``True`` if the request complete successfully otherwise it will raise an exception.\n\n```Python\nstate = users.update(id, batman_update).isOk() # Return True here.\n```\n\n#### verify\n\nDoes the same as ``isOk`` but it allow you to chain more methods.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\ncookies = users.update(id, batman_update).verify().response().cookies # Get cookies.\n```\n\n\n## Specialisations\n\n### Realms \n\n### KeycloakCaches \n\nThis class handles the Keycloak caches. \n\n#### Instantiation \n\n```python\n# Creates a REST API instance target the Realms API. \nrealms = kc.build(\'realms\', \'my_realm\') \n\n# Gets the cache Realms cache API. \ncaches = realms.caches(self.REALM)\n```\n\n#### clearUserCache \nThis method tells Keycloak to clear the user cache.\n\n```python\ncaches.clearUserCache()\n```\n\n\n#### clearRealmCache \nThis method tells Keycloak to clear the realm cache.\n\n```python\ncaches.clearRealmCache()\n```\n\n\n#### clearKeyCache \nThis method tells Keycloak to clear the external public key cache for clients and identity providers.\n\n```python\ncaches.clearKeyCache()\n```\n\n> For more information on how this caches works follow this [link](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_installation_and_configuration_guide/server_cache_configuration).\n\n\n### Users\n\n#### updateCredentials\n\nUpdate user credentials.\n\n```js\nuser_credentials = {\n \'temporary\': False,\n \'value\':\'12345\'\n}\n\nstate = users.updateCredentials(user_info, user_credentials).isOk() # Updated user password.\n```\nWhere:\n- **temporary**: Boolean where if ``True`` provide a temporary password just for the first login. \n- **value**: String with the password.\n\n\n#### joinGroup\n\nAdd a user into a existing [group](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n\nFirst we need a group:\n```python\ndef createDCGroup():\n group = kc.build(\'groups\', \'heroes\')\n return group.create({"name": "DC"}).isOk()\n```\n\nThen we can join the group the following way:\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\n> The API works by matching the first occurrence between the provided ``key/value`` for the two resources (User and Group), this can help in various situation for example if we want to target the user by ``uuid``.\n\n\nUsing ``uuid`` as user identifier.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\nOr we want to use the group ``id``:\n\n```python\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "id", "value": "f8d91722-a1f0-45e..."}\n\n users.joinGroup(user, group).isOk()\n```\n> If the field criteria don\'t return a unique value, the first entry in the list will be used.\n#### leaveGroup\n\nRemove a user from a group.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "uuid", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n user = {"key": "uuid", "value": "12d3-a456-4"}\n group = {"key": "id", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n```\n\n> The same rules for ``key/value`` discussed above also applies here.\n\n\n### Groups\n\nTo manage the relationship between realm level [roles](keycloak.org/docs/latest/server_admin/#assigning-permissions-and-access-using-roles-and-groups) and groups, we can use the **RealmsRolesMapping**.\n\nTo get an instance of this class you need to instantiate the ``group`` resource class:\n\n```Python\ngroups = kc.build(\'groups\', \'heroes\')\n```\n\nAnd use the method ``realmRoles`` passing a valid [group dictionary](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_grouprepresentation):\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n```\n\nThen we get a class with following methods:\n\n#### add\n\nAdd a list of existing roles to a group.\n\n```python\ndef makeRoles(self):\n roles = kc.build(\'roles\', self.realm)\n lvl1 = roles.create({"name": "level-1"}).isOk()\n lvl2 = roles.create({"name": "level-2"}).isOk()\n return lvl1 and lvl2\n\n\nif makeRoles():\n realmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n realmsRoles.add(["level-1", "level-2"])\n```\n\n#### remove\nRemove a list of associated roles from a group.\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\nrealmsRoles.remove(["level-1", "level-2"])\n```\n\n\n## Roles \n\n\n#### composite\nIn Keycloak we can map roles to other roles, this method allow you to do just that. \n\n```python\nrole_watch = self.kc.build(\'roles\', \'my-realm\').find(\'watch\')\nadded = role_watch.add_composite(\'view\')\n```'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'readme' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'readme' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'license' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `license = 'MIT'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'license' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'license' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'dependencies' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `dependencies = ['requests']` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'dependencies' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'dependencies' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 985, in run_command log.info("running %s", command) Message: 'running %s' Arguments: ('dist_info',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 684, in write_pkg_info log.info("writing %s", filename) Message: 'writing %s' Arguments: ('kcapi.egg-info/PKG-INFO',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 747, in overwrite_arg write_arg(cmd, basename, filename, True) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 755, in write_arg cmd.write_or_delete_file(argname, filename, value, force) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 273, in write_or_delete_file self.write_file(what, filename, data) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 289, in write_file log.info("writing %s to %s", what, filename) Message: 'writing %s to %s' Arguments: ('dependency_links', 'kcapi.egg-info/dependency_links.txt') --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 727, in write_requirements cmd.write_or_delete_file("requirements", filename, data.getvalue()) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 273, in write_or_delete_file self.write_file(what, filename, data) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 289, in write_file log.info("writing %s to %s", what, filename) Message: 'writing %s to %s' Arguments: ('requirements', 'kcapi.egg-info/requires.txt') --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 743, in write_toplevel_names cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n') File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 289, in write_file log.info("writing %s to %s", what, filename) Message: 'writing %s to %s' Arguments: ('top-level names', 'kcapi.egg-info/top_level.txt') --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 318, in run self.find_sources() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 326, in find_sources mm.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 570, in run self.add_defaults() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 615, in add_defaults self.read_manifest() File "/usr/lib/python3.11/site-packages/setuptools/command/sdist.py", line 196, in read_manifest log.info("reading manifest file '%s'", self.manifest) Message: "reading manifest file '%s'" Arguments: ('kcapi.egg-info/SOURCES.txt',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 318, in run self.find_sources() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 326, in find_sources mm.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 573, in run self.add_license_files() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 628, in add_license_files log.info("adding license file '%s'", lf) Message: "adding license file '%s'" Arguments: ('LICENSE',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 318, in run self.find_sources() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 326, in find_sources mm.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 578, in run self.write_manifest() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 594, in write_manifest self.execute(write_file, (self.manifest, files), msg) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/cmd.py", line 339, in execute util.execute(func, args, msg, dry_run=self.dry_run) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/util.py", line 335, in execute log.info(msg) Message: "writing manifest file 'kcapi.egg-info/SOURCES.txt'" Arguments: () --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 102, in run log.info("creating '{}'".format(os.path.abspath(self.dist_info_dir))) Message: "creating '/builddir/build/BUILD/kcapi-1.1.2/kcapi-1.1.2.dist-info'" Arguments: () Handling requests from hook generated metadata: Requires-Dist Requirement satisfied: requests (installed: requests 2.28.2) + rm -rfv kcapi-1.1.2.dist-info/ removed 'kcapi-1.1.2.dist-info/LICENSE' removed 'kcapi-1.1.2.dist-info/METADATA' removed 'kcapi-1.1.2.dist-info/top_level.txt' removed directory 'kcapi-1.1.2.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-kcapi-1.1.2-1.fc39.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -ba --noprep --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1001gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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']unshare_net=TrueprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', 'a17e773f3b184bf4a65bb3eb9e21458b', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1680034719.565172/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.bu_xgw8h:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/mapper/control', '--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', '--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', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -ba --noprep --target x86_64 --nodeps /builddir/build/SPECS/python-kcapi.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0', 'SYSTEMD_SECCOMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1679961600 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.5sbQOS + umask 022 + cd /builddir/build/BUILD + cd kcapi-1.1.2 + 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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + echo pyproject-rpm-macros + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + echo '(python3dist(toml) if python3-devel < 3.11)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + mkdir -p /builddir/build/BUILD/kcapi-1.1.2/.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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + TMPDIR=/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir + RPM_TOXENV=py311 + HOSTNAME=rpmbuild + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 --wheeldir /builddir/build/BUILD/kcapi-1.1.2/pyproject-wheeldir Handling setuptools>=61.0 from build-system.requires Requirement satisfied: setuptools>=61.0 (installed: setuptools 67.6.1) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'readme' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `readme = '# Keycloak API\n\nPython module to automate Keycloak or Red Hat Single Sign-On (RHSSO) configuration.\n\n## How To Install\n\n```sh\npip install kcapi\n```\n\n\n## Testing\n\nTo run the test you would need a Keycloak instance, you can run one locally or in the [cloud]( https://developers.redhat.com/developer-sandbox/get-started) then you just have to follow this steps: \n\n```shell script\npython3.10 -m venv .venv\nsource .venv/bin/activate\npip install requests\n\n# Setup SSO server - go to https://developers.redhat.com/developer-sandbox/get-started,\n# launch sandbox environment, +Add, select some "Red Hat Single Sign-On..." template.\nexport KC_USER=admin\nexport KC_PASSWORD=admin_password\nexport KC_REALM=myrealm # do not use master realm, it cannot be removed\nexport KC_ENDPOINT=https://my-first-sso-me-me-dev.apps.sandbox.x8i5.p1.openshiftapps.com\n\npython -m unittest\n```\n\n\n## API\n\n### OpenID\n\nThis class takes care of OpenID login using [password owner credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3) flow.\n\n\n#### Constructor\n\n```python\nfrom rhsso import OpenID\n\noid_client = OpenID({\n "client_id": "admin-cli",\n "username": USER,\n "password": PASSWORD,\n "grant_type":"password",\n "realm" : "master"\n }, endpoint)\n```\n\n- **client_id**: Client Identifier in Keycloak.\n- **username**: Login username for the Realm.\n- **password**: Login password for the Realm.\n- **grant_type**: The grant type you want to use (usually ``password``).\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n##### getToken\n\nThis will initiate a session with the Keycloak server and will return a OpenID token back.\n\n```python\noid_client.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n\n##### createAdminClient\n\nThis static method should be used in order to access the master Realm in Keycloak.\n\n```python\n oidc = OpenID.createAdminClient(self.USER, self.PASSWORD)\n oidc.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n### Keycloak\n\nThis class builds all the Keycloak configuration REST resources by using REST conventions we can target the majority of Keycloak services.\n\n#### Constructor\n\n```Python\nkc = Keycloak(token, self.ENDPOINT)\n```\n\nThe constructor takes two parameters:\n\n- **token**: A token with enough priviledge to perform the desired operation.\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n#### build\nThis methods build a REST client (capabilities detailed below) targeting a specific Keycloak REST resource.\n\n```python\ngroups = kc.build(\'groups\', \'my_realm\')\n\n# Create a group called DC\nstate = groups.create({"name": "DC"}).isOk()\n\n```\n> In this example we build the \'groups\' API for ``my_realm`` Realm.\n\n##### Supported Resources\n\nHere is a quick list of supported resources:\n\n- **users**: [users API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_user).\n- **clients**: [client API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_client). \n- **groups**: [groups API](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n- **roles**: [roles API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_role_for_the_realm_or_client_2)\n- **identity-provider**: [identity provider API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_get_identity_providers)\n\n\n> As long as you find a REST endpoint that follow the standard you can use this method to build a client around it, an example of this is the non well documented ``components`` endpoint.\n\n- **components**: This API allows you configure things like [user federation](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/user-storage-federation) or [Realm keys](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/admin_permissions#realm_keys).\n\n- **authentication**: Provide access to built-in and/or custom authentication flows.\n
\n\n#### admin\nSimilar to the ``build`` method but the client points to the ``master`` realm, allowing us operation such as realm creation.\n\n```python\n main_realm = kc.admin()\n\n # Creates a realm called my_realm\n main_realm.create({"enabled": "true", "id": my_realm, "realm": my_realm})\n```\n\n\n### REST API\n\nWhen you use the ``build`` or ``admin`` methods you will get back a **REST** class pointing to the Keycloak resource, keep in mind that this class don\'t check that the resource is valid, this is done to keep it flexible and to make it easy to adapt to new Keycloak REST API changes in the future. \n\n#### Usage\n\nIn order to create one you need to ``build`` method we have used before:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nstate = users.create(batman).isOk()\n```\n\n#### Methods\n\nFollowing the example above lets see the methods we have starting with the usual CRUD methods:\n\n#### create\n\nThis method ``POST`` a dictionary into any given resource:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nstate = users.create(batman).isOk()\n```\n\n- **dictionary**: Dictionary with the fields we want to POST to the server.\n\n\n\n\n#### update\n\nThis method performs a ``PUT`` on the resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.update(id, batman_update).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n#### remove\nThis method sends a ``DELETE`` to the pointed resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.remove(id).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n\n#### get\nSend a ``GET`` request to retrieve a specific Keycloak resource.\n\n```python\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nuser = users.get(id).response()\n```\n\n#### all\n\nReturn all objects of a particular resource type.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nuser_list = users.all() #\xa0[ {id:\'xxx-yyy\', username: \'batman\', ...} ] \n```\n#### findFirst\nFinds a resource by passing an arbitrary key/value pair.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.findFirst({"key":"username", "value": \'batman\'})\n```\n\n#### exist\nCheck if a resource matching the provided ``id`` exists:\n```Python\nusers = kc.build(\'users\', \'DC\')\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nusers.exists(id) #True\n```\n\n#### existByKV\nCheck if a resource matching the provided key/value pair, exists.\n\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.existByKV("username", \'batman\') #False\n```\n\n\n### ResponseHandler\n\nEach **CRUD** method returns a ``ResponseHandler`` class with the following methods.\n\n#### Methods\n\n\n#### response\nreturns the requests [response object](https://docs.python-requests.org/en/latest/api/#requests.Response).\n\n```Python\nusers.update(id, batman_update).response().status_code #HTTP 201\n```\n\n\n#### isOk\n\nReturn ``True`` if the request complete successfully otherwise it will raise an exception.\n\n```Python\nstate = users.update(id, batman_update).isOk() # Return True here.\n```\n\n#### verify\n\nDoes the same as ``isOk`` but it allow you to chain more methods.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\ncookies = users.update(id, batman_update).verify().response().cookies # Get cookies.\n```\n\n\n## Specialisations\n\n### Realms \n\n### KeycloakCaches \n\nThis class handles the Keycloak caches. \n\n#### Instantiation \n\n```python\n# Creates a REST API instance target the Realms API. \nrealms = kc.build(\'realms\', \'my_realm\') \n\n# Gets the cache Realms cache API. \ncaches = realms.caches(self.REALM)\n```\n\n#### clearUserCache \nThis method tells Keycloak to clear the user cache.\n\n```python\ncaches.clearUserCache()\n```\n\n\n#### clearRealmCache \nThis method tells Keycloak to clear the realm cache.\n\n```python\ncaches.clearRealmCache()\n```\n\n\n#### clearKeyCache \nThis method tells Keycloak to clear the external public key cache for clients and identity providers.\n\n```python\ncaches.clearKeyCache()\n```\n\n> For more information on how this caches works follow this [link](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_installation_and_configuration_guide/server_cache_configuration).\n\n\n### Users\n\n#### updateCredentials\n\nUpdate user credentials.\n\n```js\nuser_credentials = {\n \'temporary\': False,\n \'value\':\'12345\'\n}\n\nstate = users.updateCredentials(user_info, user_credentials).isOk() # Updated user password.\n```\nWhere:\n- **temporary**: Boolean where if ``True`` provide a temporary password just for the first login. \n- **value**: String with the password.\n\n\n#### joinGroup\n\nAdd a user into a existing [group](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n\nFirst we need a group:\n```python\ndef createDCGroup():\n group = kc.build(\'groups\', \'heroes\')\n return group.create({"name": "DC"}).isOk()\n```\n\nThen we can join the group the following way:\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\n> The API works by matching the first occurrence between the provided ``key/value`` for the two resources (User and Group), this can help in various situation for example if we want to target the user by ``uuid``.\n\n\nUsing ``uuid`` as user identifier.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\nOr we want to use the group ``id``:\n\n```python\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "id", "value": "f8d91722-a1f0-45e..."}\n\n users.joinGroup(user, group).isOk()\n```\n> If the field criteria don\'t return a unique value, the first entry in the list will be used.\n#### leaveGroup\n\nRemove a user from a group.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "uuid", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n user = {"key": "uuid", "value": "12d3-a456-4"}\n group = {"key": "id", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n```\n\n> The same rules for ``key/value`` discussed above also applies here.\n\n\n### Groups\n\nTo manage the relationship between realm level [roles](keycloak.org/docs/latest/server_admin/#assigning-permissions-and-access-using-roles-and-groups) and groups, we can use the **RealmsRolesMapping**.\n\nTo get an instance of this class you need to instantiate the ``group`` resource class:\n\n```Python\ngroups = kc.build(\'groups\', \'heroes\')\n```\n\nAnd use the method ``realmRoles`` passing a valid [group dictionary](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_grouprepresentation):\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n```\n\nThen we get a class with following methods:\n\n#### add\n\nAdd a list of existing roles to a group.\n\n```python\ndef makeRoles(self):\n roles = kc.build(\'roles\', self.realm)\n lvl1 = roles.create({"name": "level-1"}).isOk()\n lvl2 = roles.create({"name": "level-2"}).isOk()\n return lvl1 and lvl2\n\n\nif makeRoles():\n realmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n realmsRoles.add(["level-1", "level-2"])\n```\n\n#### remove\nRemove a list of associated roles from a group.\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\nrealmsRoles.remove(["level-1", "level-2"])\n```\n\n\n## Roles \n\n\n#### composite\nIn Keycloak we can map roles to other roles, this method allow you to do just that. \n\n```python\nrole_watch = self.kc.build(\'roles\', \'my-realm\').find(\'watch\')\nadded = role_watch.add_composite(\'view\')\n```'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'readme' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'readme' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'license' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `license = 'MIT'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'license' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'license' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'dependencies' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `dependencies = ['requests']` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'dependencies' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'dependencies' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) HOOK STDOUT: running egg_info HOOK STDOUT: writing kcapi.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to kcapi.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to kcapi.egg-info/requires.txt HOOK STDOUT: writing top-level names to kcapi.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'kcapi.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'kcapi.egg-info/SOURCES.txt' Handling wheel from get_requires_for_build_wheel Requirement satisfied: wheel (installed: wheel 0.38.4) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'readme' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `readme = '# Keycloak API\n\nPython module to automate Keycloak or Red Hat Single Sign-On (RHSSO) configuration.\n\n## How To Install\n\n```sh\npip install kcapi\n```\n\n\n## Testing\n\nTo run the test you would need a Keycloak instance, you can run one locally or in the [cloud]( https://developers.redhat.com/developer-sandbox/get-started) then you just have to follow this steps: \n\n```shell script\npython3.10 -m venv .venv\nsource .venv/bin/activate\npip install requests\n\n# Setup SSO server - go to https://developers.redhat.com/developer-sandbox/get-started,\n# launch sandbox environment, +Add, select some "Red Hat Single Sign-On..." template.\nexport KC_USER=admin\nexport KC_PASSWORD=admin_password\nexport KC_REALM=myrealm # do not use master realm, it cannot be removed\nexport KC_ENDPOINT=https://my-first-sso-me-me-dev.apps.sandbox.x8i5.p1.openshiftapps.com\n\npython -m unittest\n```\n\n\n## API\n\n### OpenID\n\nThis class takes care of OpenID login using [password owner credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3) flow.\n\n\n#### Constructor\n\n```python\nfrom rhsso import OpenID\n\noid_client = OpenID({\n "client_id": "admin-cli",\n "username": USER,\n "password": PASSWORD,\n "grant_type":"password",\n "realm" : "master"\n }, endpoint)\n```\n\n- **client_id**: Client Identifier in Keycloak.\n- **username**: Login username for the Realm.\n- **password**: Login password for the Realm.\n- **grant_type**: The grant type you want to use (usually ``password``).\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n##### getToken\n\nThis will initiate a session with the Keycloak server and will return a OpenID token back.\n\n```python\noid_client.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n\n##### createAdminClient\n\nThis static method should be used in order to access the master Realm in Keycloak.\n\n```python\n oidc = OpenID.createAdminClient(self.USER, self.PASSWORD)\n oidc.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n### Keycloak\n\nThis class builds all the Keycloak configuration REST resources by using REST conventions we can target the majority of Keycloak services.\n\n#### Constructor\n\n```Python\nkc = Keycloak(token, self.ENDPOINT)\n```\n\nThe constructor takes two parameters:\n\n- **token**: A token with enough priviledge to perform the desired operation.\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n#### build\nThis methods build a REST client (capabilities detailed below) targeting a specific Keycloak REST resource.\n\n```python\ngroups = kc.build(\'groups\', \'my_realm\')\n\n# Create a group called DC\nstate = groups.create({"name": "DC"}).isOk()\n\n```\n> In this example we build the \'groups\' API for ``my_realm`` Realm.\n\n##### Supported Resources\n\nHere is a quick list of supported resources:\n\n- **users**: [users API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_user).\n- **clients**: [client API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_client). \n- **groups**: [groups API](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n- **roles**: [roles API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_role_for_the_realm_or_client_2)\n- **identity-provider**: [identity provider API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_get_identity_providers)\n\n\n> As long as you find a REST endpoint that follow the standard you can use this method to build a client around it, an example of this is the non well documented ``components`` endpoint.\n\n- **components**: This API allows you configure things like [user federation](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/user-storage-federation) or [Realm keys](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/admin_permissions#realm_keys).\n\n- **authentication**: Provide access to built-in and/or custom authentication flows.\n
\n\n#### admin\nSimilar to the ``build`` method but the client points to the ``master`` realm, allowing us operation such as realm creation.\n\n```python\n main_realm = kc.admin()\n\n # Creates a realm called my_realm\n main_realm.create({"enabled": "true", "id": my_realm, "realm": my_realm})\n```\n\n\n### REST API\n\nWhen you use the ``build`` or ``admin`` methods you will get back a **REST** class pointing to the Keycloak resource, keep in mind that this class don\'t check that the resource is valid, this is done to keep it flexible and to make it easy to adapt to new Keycloak REST API changes in the future. \n\n#### Usage\n\nIn order to create one you need to ``build`` method we have used before:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nstate = users.create(batman).isOk()\n```\n\n#### Methods\n\nFollowing the example above lets see the methods we have starting with the usual CRUD methods:\n\n#### create\n\nThis method ``POST`` a dictionary into any given resource:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nstate = users.create(batman).isOk()\n```\n\n- **dictionary**: Dictionary with the fields we want to POST to the server.\n\n\n\n\n#### update\n\nThis method performs a ``PUT`` on the resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.update(id, batman_update).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n#### remove\nThis method sends a ``DELETE`` to the pointed resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.remove(id).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n\n#### get\nSend a ``GET`` request to retrieve a specific Keycloak resource.\n\n```python\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nuser = users.get(id).response()\n```\n\n#### all\n\nReturn all objects of a particular resource type.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nuser_list = users.all() #\xa0[ {id:\'xxx-yyy\', username: \'batman\', ...} ] \n```\n#### findFirst\nFinds a resource by passing an arbitrary key/value pair.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.findFirst({"key":"username", "value": \'batman\'})\n```\n\n#### exist\nCheck if a resource matching the provided ``id`` exists:\n```Python\nusers = kc.build(\'users\', \'DC\')\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nusers.exists(id) #True\n```\n\n#### existByKV\nCheck if a resource matching the provided key/value pair, exists.\n\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.existByKV("username", \'batman\') #False\n```\n\n\n### ResponseHandler\n\nEach **CRUD** method returns a ``ResponseHandler`` class with the following methods.\n\n#### Methods\n\n\n#### response\nreturns the requests [response object](https://docs.python-requests.org/en/latest/api/#requests.Response).\n\n```Python\nusers.update(id, batman_update).response().status_code #HTTP 201\n```\n\n\n#### isOk\n\nReturn ``True`` if the request complete successfully otherwise it will raise an exception.\n\n```Python\nstate = users.update(id, batman_update).isOk() # Return True here.\n```\n\n#### verify\n\nDoes the same as ``isOk`` but it allow you to chain more methods.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\ncookies = users.update(id, batman_update).verify().response().cookies # Get cookies.\n```\n\n\n## Specialisations\n\n### Realms \n\n### KeycloakCaches \n\nThis class handles the Keycloak caches. \n\n#### Instantiation \n\n```python\n# Creates a REST API instance target the Realms API. \nrealms = kc.build(\'realms\', \'my_realm\') \n\n# Gets the cache Realms cache API. \ncaches = realms.caches(self.REALM)\n```\n\n#### clearUserCache \nThis method tells Keycloak to clear the user cache.\n\n```python\ncaches.clearUserCache()\n```\n\n\n#### clearRealmCache \nThis method tells Keycloak to clear the realm cache.\n\n```python\ncaches.clearRealmCache()\n```\n\n\n#### clearKeyCache \nThis method tells Keycloak to clear the external public key cache for clients and identity providers.\n\n```python\ncaches.clearKeyCache()\n```\n\n> For more information on how this caches works follow this [link](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_installation_and_configuration_guide/server_cache_configuration).\n\n\n### Users\n\n#### updateCredentials\n\nUpdate user credentials.\n\n```js\nuser_credentials = {\n \'temporary\': False,\n \'value\':\'12345\'\n}\n\nstate = users.updateCredentials(user_info, user_credentials).isOk() # Updated user password.\n```\nWhere:\n- **temporary**: Boolean where if ``True`` provide a temporary password just for the first login. \n- **value**: String with the password.\n\n\n#### joinGroup\n\nAdd a user into a existing [group](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n\nFirst we need a group:\n```python\ndef createDCGroup():\n group = kc.build(\'groups\', \'heroes\')\n return group.create({"name": "DC"}).isOk()\n```\n\nThen we can join the group the following way:\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\n> The API works by matching the first occurrence between the provided ``key/value`` for the two resources (User and Group), this can help in various situation for example if we want to target the user by ``uuid``.\n\n\nUsing ``uuid`` as user identifier.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\nOr we want to use the group ``id``:\n\n```python\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "id", "value": "f8d91722-a1f0-45e..."}\n\n users.joinGroup(user, group).isOk()\n```\n> If the field criteria don\'t return a unique value, the first entry in the list will be used.\n#### leaveGroup\n\nRemove a user from a group.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "uuid", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n user = {"key": "uuid", "value": "12d3-a456-4"}\n group = {"key": "id", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n```\n\n> The same rules for ``key/value`` discussed above also applies here.\n\n\n### Groups\n\nTo manage the relationship between realm level [roles](keycloak.org/docs/latest/server_admin/#assigning-permissions-and-access-using-roles-and-groups) and groups, we can use the **RealmsRolesMapping**.\n\nTo get an instance of this class you need to instantiate the ``group`` resource class:\n\n```Python\ngroups = kc.build(\'groups\', \'heroes\')\n```\n\nAnd use the method ``realmRoles`` passing a valid [group dictionary](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_grouprepresentation):\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n```\n\nThen we get a class with following methods:\n\n#### add\n\nAdd a list of existing roles to a group.\n\n```python\ndef makeRoles(self):\n roles = kc.build(\'roles\', self.realm)\n lvl1 = roles.create({"name": "level-1"}).isOk()\n lvl2 = roles.create({"name": "level-2"}).isOk()\n return lvl1 and lvl2\n\n\nif makeRoles():\n realmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n realmsRoles.add(["level-1", "level-2"])\n```\n\n#### remove\nRemove a list of associated roles from a group.\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\nrealmsRoles.remove(["level-1", "level-2"])\n```\n\n\n## Roles \n\n\n#### composite\nIn Keycloak we can map roles to other roles, this method allow you to do just that. \n\n```python\nrole_watch = self.kc.build(\'roles\', \'my-realm\').find(\'watch\')\nadded = role_watch.add_composite(\'view\')\n```'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'readme' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'readme' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'license' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `license = 'MIT'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'license' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'license' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'dependencies' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `dependencies = ['requests']` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'dependencies' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'dependencies' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 985, in run_command log.info("running %s", command) Message: 'running %s' Arguments: ('dist_info',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 684, in write_pkg_info log.info("writing %s", filename) Message: 'writing %s' Arguments: ('kcapi.egg-info/PKG-INFO',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 747, in overwrite_arg write_arg(cmd, basename, filename, True) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 755, in write_arg cmd.write_or_delete_file(argname, filename, value, force) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 273, in write_or_delete_file self.write_file(what, filename, data) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 289, in write_file log.info("writing %s to %s", what, filename) Message: 'writing %s to %s' Arguments: ('dependency_links', 'kcapi.egg-info/dependency_links.txt') --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 727, in write_requirements cmd.write_or_delete_file("requirements", filename, data.getvalue()) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 273, in write_or_delete_file self.write_file(what, filename, data) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 289, in write_file log.info("writing %s to %s", what, filename) Message: 'writing %s to %s' Arguments: ('requirements', 'kcapi.egg-info/requires.txt') --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 311, in run writer(self, ep.name, os.path.join(self.egg_info, ep.name)) File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 743, in write_toplevel_names cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n') File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 289, in write_file log.info("writing %s to %s", what, filename) Message: 'writing %s to %s' Arguments: ('top-level names', 'kcapi.egg-info/top_level.txt') --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 318, in run self.find_sources() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 326, in find_sources mm.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 570, in run self.add_defaults() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 615, in add_defaults self.read_manifest() File "/usr/lib/python3.11/site-packages/setuptools/command/sdist.py", line 196, in read_manifest log.info("reading manifest file '%s'", self.manifest) Message: "reading manifest file '%s'" Arguments: ('kcapi.egg-info/SOURCES.txt',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 318, in run self.find_sources() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 326, in find_sources mm.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 573, in run self.add_license_files() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 628, in add_license_files log.info("adding license file '%s'", lf) Message: "adding license file '%s'" Arguments: ('LICENSE',) --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 98, in run self.egg_info.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 318, in run self.find_sources() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 326, in find_sources mm.run() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 578, in run self.write_manifest() File "/usr/lib/python3.11/site-packages/setuptools/command/egg_info.py", line 594, in write_manifest self.execute(write_file, (self.manifest, files), msg) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/cmd.py", line 339, in execute util.execute(func, args, msg, dry_run=self.dry_run) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/util.py", line 335, in execute log.info(msg) Message: "writing manifest file 'kcapi.egg-info/SOURCES.txt'" Arguments: () --- Logging error --- Traceback (most recent call last): File "/usr/lib64/python3.11/logging/__init__.py", line 1113, in emit stream.write(msg + self.terminator) ValueError: I/O operation on closed file. Call stack: File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 550, in main(sys.argv[1:]) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 532, in main generate_requires( File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 444, in generate_requires generate_run_requirements(backend, requirements, build_wheel=build_wheel, wheeldir=wheeldir) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 354, in generate_run_requirements generate_run_requirements_hook(backend, requirements) File "/usr/lib/rpm/redhat/pyproject_buildrequires.py", line 310, in generate_run_requirements_hook dir_basename = prepare_metadata('.') File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 377, in prepare_metadata_for_build_wheel self.run_setup() File "/usr/lib/python3.11/site-packages/setuptools/build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 8, in File "/usr/lib/python3.11/site-packages/setuptools/__init__.py", line 108, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 185, in setup return run_commands(dist) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 201, in run_commands dist.run_commands() File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands self.run_command(cmd) File "/usr/lib/python3.11/site-packages/setuptools/dist.py", line 1221, in run_command super().run_command(command) File "/usr/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 988, in run_command cmd_obj.run() File "/usr/lib/python3.11/site-packages/setuptools/command/dist_info.py", line 102, in run log.info("creating '{}'".format(os.path.abspath(self.dist_info_dir))) Message: "creating '/builddir/build/BUILD/kcapi-1.1.2/kcapi-1.1.2.dist-info'" Arguments: () Handling requests from hook generated metadata: Requires-Dist Requirement satisfied: requests (installed: requests 2.28.2) + rm -rfv kcapi-1.1.2.dist-info/ removed 'kcapi-1.1.2.dist-info/LICENSE' removed 'kcapi-1.1.2.dist-info/METADATA' removed 'kcapi-1.1.2.dist-info/top_level.txt' removed directory 'kcapi-1.1.2.dist-info/' + RPM_EC=0 ++ jobs -p + exit 0 Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.aWwCAa + umask 022 + cd /builddir/build/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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -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 kcapi-1.1.2 + mkdir -p /builddir/build/BUILD/kcapi-1.1.2/.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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes ' + TMPDIR=/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir + /usr/bin/python3 -Bs /usr/lib/rpm/redhat/pyproject_wheel.py /builddir/build/BUILD/kcapi-1.1.2/pyproject-wheeldir Processing /builddir/build/BUILD/kcapi-1.1.2 Preparing metadata (pyproject.toml): started Running command Preparing metadata (pyproject.toml) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'readme' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `readme = '# Keycloak API\n\nPython module to automate Keycloak or Red Hat Single Sign-On (RHSSO) configuration.\n\n## How To Install\n\n```sh\npip install kcapi\n```\n\n\n## Testing\n\nTo run the test you would need a Keycloak instance, you can run one locally or in the [cloud]( https://developers.redhat.com/developer-sandbox/get-started) then you just have to follow this steps: \n\n```shell script\npython3.10 -m venv .venv\nsource .venv/bin/activate\npip install requests\n\n# Setup SSO server - go to https://developers.redhat.com/developer-sandbox/get-started,\n# launch sandbox environment, +Add, select some "Red Hat Single Sign-On..." template.\nexport KC_USER=admin\nexport KC_PASSWORD=admin_password\nexport KC_REALM=myrealm # do not use master realm, it cannot be removed\nexport KC_ENDPOINT=https://my-first-sso-me-me-dev.apps.sandbox.x8i5.p1.openshiftapps.com\n\npython -m unittest\n```\n\n\n## API\n\n### OpenID\n\nThis class takes care of OpenID login using [password owner credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3) flow.\n\n\n#### Constructor\n\n```python\nfrom rhsso import OpenID\n\noid_client = OpenID({\n "client_id": "admin-cli",\n "username": USER,\n "password": PASSWORD,\n "grant_type":"password",\n "realm" : "master"\n }, endpoint)\n```\n\n- **client_id**: Client Identifier in Keycloak.\n- **username**: Login username for the Realm.\n- **password**: Login password for the Realm.\n- **grant_type**: The grant type you want to use (usually ``password``).\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n##### getToken\n\nThis will initiate a session with the Keycloak server and will return a OpenID token back.\n\n```python\noid_client.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n\n##### createAdminClient\n\nThis static method should be used in order to access the master Realm in Keycloak.\n\n```python\n oidc = OpenID.createAdminClient(self.USER, self.PASSWORD)\n oidc.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n### Keycloak\n\nThis class builds all the Keycloak configuration REST resources by using REST conventions we can target the majority of Keycloak services.\n\n#### Constructor\n\n```Python\nkc = Keycloak(token, self.ENDPOINT)\n```\n\nThe constructor takes two parameters:\n\n- **token**: A token with enough priviledge to perform the desired operation.\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n#### build\nThis methods build a REST client (capabilities detailed below) targeting a specific Keycloak REST resource.\n\n```python\ngroups = kc.build(\'groups\', \'my_realm\')\n\n# Create a group called DC\nstate = groups.create({"name": "DC"}).isOk()\n\n```\n> In this example we build the \'groups\' API for ``my_realm`` Realm.\n\n##### Supported Resources\n\nHere is a quick list of supported resources:\n\n- **users**: [users API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_user).\n- **clients**: [client API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_client). \n- **groups**: [groups API](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n- **roles**: [roles API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_role_for_the_realm_or_client_2)\n- **identity-provider**: [identity provider API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_get_identity_providers)\n\n\n> As long as you find a REST endpoint that follow the standard you can use this method to build a client around it, an example of this is the non well documented ``components`` endpoint.\n\n- **components**: This API allows you configure things like [user federation](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/user-storage-federation) or [Realm keys](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/admin_permissions#realm_keys).\n\n- **authentication**: Provide access to built-in and/or custom authentication flows.\n
\n\n#### admin\nSimilar to the ``build`` method but the client points to the ``master`` realm, allowing us operation such as realm creation.\n\n```python\n main_realm = kc.admin()\n\n # Creates a realm called my_realm\n main_realm.create({"enabled": "true", "id": my_realm, "realm": my_realm})\n```\n\n\n### REST API\n\nWhen you use the ``build`` or ``admin`` methods you will get back a **REST** class pointing to the Keycloak resource, keep in mind that this class don\'t check that the resource is valid, this is done to keep it flexible and to make it easy to adapt to new Keycloak REST API changes in the future. \n\n#### Usage\n\nIn order to create one you need to ``build`` method we have used before:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nstate = users.create(batman).isOk()\n```\n\n#### Methods\n\nFollowing the example above lets see the methods we have starting with the usual CRUD methods:\n\n#### create\n\nThis method ``POST`` a dictionary into any given resource:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nstate = users.create(batman).isOk()\n```\n\n- **dictionary**: Dictionary with the fields we want to POST to the server.\n\n\n\n\n#### update\n\nThis method performs a ``PUT`` on the resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.update(id, batman_update).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n#### remove\nThis method sends a ``DELETE`` to the pointed resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.remove(id).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n\n#### get\nSend a ``GET`` request to retrieve a specific Keycloak resource.\n\n```python\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nuser = users.get(id).response()\n```\n\n#### all\n\nReturn all objects of a particular resource type.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nuser_list = users.all() #\xa0[ {id:\'xxx-yyy\', username: \'batman\', ...} ] \n```\n#### findFirst\nFinds a resource by passing an arbitrary key/value pair.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.findFirst({"key":"username", "value": \'batman\'})\n```\n\n#### exist\nCheck if a resource matching the provided ``id`` exists:\n```Python\nusers = kc.build(\'users\', \'DC\')\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nusers.exists(id) #True\n```\n\n#### existByKV\nCheck if a resource matching the provided key/value pair, exists.\n\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.existByKV("username", \'batman\') #False\n```\n\n\n### ResponseHandler\n\nEach **CRUD** method returns a ``ResponseHandler`` class with the following methods.\n\n#### Methods\n\n\n#### response\nreturns the requests [response object](https://docs.python-requests.org/en/latest/api/#requests.Response).\n\n```Python\nusers.update(id, batman_update).response().status_code #HTTP 201\n```\n\n\n#### isOk\n\nReturn ``True`` if the request complete successfully otherwise it will raise an exception.\n\n```Python\nstate = users.update(id, batman_update).isOk() # Return True here.\n```\n\n#### verify\n\nDoes the same as ``isOk`` but it allow you to chain more methods.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\ncookies = users.update(id, batman_update).verify().response().cookies # Get cookies.\n```\n\n\n## Specialisations\n\n### Realms \n\n### KeycloakCaches \n\nThis class handles the Keycloak caches. \n\n#### Instantiation \n\n```python\n# Creates a REST API instance target the Realms API. \nrealms = kc.build(\'realms\', \'my_realm\') \n\n# Gets the cache Realms cache API. \ncaches = realms.caches(self.REALM)\n```\n\n#### clearUserCache \nThis method tells Keycloak to clear the user cache.\n\n```python\ncaches.clearUserCache()\n```\n\n\n#### clearRealmCache \nThis method tells Keycloak to clear the realm cache.\n\n```python\ncaches.clearRealmCache()\n```\n\n\n#### clearKeyCache \nThis method tells Keycloak to clear the external public key cache for clients and identity providers.\n\n```python\ncaches.clearKeyCache()\n```\n\n> For more information on how this caches works follow this [link](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_installation_and_configuration_guide/server_cache_configuration).\n\n\n### Users\n\n#### updateCredentials\n\nUpdate user credentials.\n\n```js\nuser_credentials = {\n \'temporary\': False,\n \'value\':\'12345\'\n}\n\nstate = users.updateCredentials(user_info, user_credentials).isOk() # Updated user password.\n```\nWhere:\n- **temporary**: Boolean where if ``True`` provide a temporary password just for the first login. \n- **value**: String with the password.\n\n\n#### joinGroup\n\nAdd a user into a existing [group](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n\nFirst we need a group:\n```python\ndef createDCGroup():\n group = kc.build(\'groups\', \'heroes\')\n return group.create({"name": "DC"}).isOk()\n```\n\nThen we can join the group the following way:\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\n> The API works by matching the first occurrence between the provided ``key/value`` for the two resources (User and Group), this can help in various situation for example if we want to target the user by ``uuid``.\n\n\nUsing ``uuid`` as user identifier.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\nOr we want to use the group ``id``:\n\n```python\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "id", "value": "f8d91722-a1f0-45e..."}\n\n users.joinGroup(user, group).isOk()\n```\n> If the field criteria don\'t return a unique value, the first entry in the list will be used.\n#### leaveGroup\n\nRemove a user from a group.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "uuid", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n user = {"key": "uuid", "value": "12d3-a456-4"}\n group = {"key": "id", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n```\n\n> The same rules for ``key/value`` discussed above also applies here.\n\n\n### Groups\n\nTo manage the relationship between realm level [roles](keycloak.org/docs/latest/server_admin/#assigning-permissions-and-access-using-roles-and-groups) and groups, we can use the **RealmsRolesMapping**.\n\nTo get an instance of this class you need to instantiate the ``group`` resource class:\n\n```Python\ngroups = kc.build(\'groups\', \'heroes\')\n```\n\nAnd use the method ``realmRoles`` passing a valid [group dictionary](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_grouprepresentation):\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n```\n\nThen we get a class with following methods:\n\n#### add\n\nAdd a list of existing roles to a group.\n\n```python\ndef makeRoles(self):\n roles = kc.build(\'roles\', self.realm)\n lvl1 = roles.create({"name": "level-1"}).isOk()\n lvl2 = roles.create({"name": "level-2"}).isOk()\n return lvl1 and lvl2\n\n\nif makeRoles():\n realmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n realmsRoles.add(["level-1", "level-2"])\n```\n\n#### remove\nRemove a list of associated roles from a group.\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\nrealmsRoles.remove(["level-1", "level-2"])\n```\n\n\n## Roles \n\n\n#### composite\nIn Keycloak we can map roles to other roles, this method allow you to do just that. \n\n```python\nrole_watch = self.kc.build(\'roles\', \'my-realm\').find(\'watch\')\nadded = role_watch.add_composite(\'view\')\n```'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'readme' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'readme' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'license' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `license = 'MIT'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'license' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'license' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'dependencies' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `dependencies = ['requests']` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'dependencies' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'dependencies' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) running dist_info creating /builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-modern-metadata-d8wqrqpq/kcapi.egg-info writing /builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-modern-metadata-d8wqrqpq/kcapi.egg-info/PKG-INFO writing dependency_links to /builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-modern-metadata-d8wqrqpq/kcapi.egg-info/dependency_links.txt writing requirements to /builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-modern-metadata-d8wqrqpq/kcapi.egg-info/requires.txt writing top-level names to /builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-modern-metadata-d8wqrqpq/kcapi.egg-info/top_level.txt writing manifest file '/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-modern-metadata-d8wqrqpq/kcapi.egg-info/SOURCES.txt' reading manifest file '/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-modern-metadata-d8wqrqpq/kcapi.egg-info/SOURCES.txt' adding license file 'LICENSE' writing manifest file '/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-modern-metadata-d8wqrqpq/kcapi.egg-info/SOURCES.txt' creating '/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-modern-metadata-d8wqrqpq/kcapi-1.1.2.dist-info' Preparing metadata (pyproject.toml): finished with status 'done' Building wheels for collected packages: kcapi Building wheel for kcapi (pyproject.toml): started Running command Building wheel for kcapi (pyproject.toml) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'readme' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `readme = '# Keycloak API\n\nPython module to automate Keycloak or Red Hat Single Sign-On (RHSSO) configuration.\n\n## How To Install\n\n```sh\npip install kcapi\n```\n\n\n## Testing\n\nTo run the test you would need a Keycloak instance, you can run one locally or in the [cloud]( https://developers.redhat.com/developer-sandbox/get-started) then you just have to follow this steps: \n\n```shell script\npython3.10 -m venv .venv\nsource .venv/bin/activate\npip install requests\n\n# Setup SSO server - go to https://developers.redhat.com/developer-sandbox/get-started,\n# launch sandbox environment, +Add, select some "Red Hat Single Sign-On..." template.\nexport KC_USER=admin\nexport KC_PASSWORD=admin_password\nexport KC_REALM=myrealm # do not use master realm, it cannot be removed\nexport KC_ENDPOINT=https://my-first-sso-me-me-dev.apps.sandbox.x8i5.p1.openshiftapps.com\n\npython -m unittest\n```\n\n\n## API\n\n### OpenID\n\nThis class takes care of OpenID login using [password owner credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3) flow.\n\n\n#### Constructor\n\n```python\nfrom rhsso import OpenID\n\noid_client = OpenID({\n "client_id": "admin-cli",\n "username": USER,\n "password": PASSWORD,\n "grant_type":"password",\n "realm" : "master"\n }, endpoint)\n```\n\n- **client_id**: Client Identifier in Keycloak.\n- **username**: Login username for the Realm.\n- **password**: Login password for the Realm.\n- **grant_type**: The grant type you want to use (usually ``password``).\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n##### getToken\n\nThis will initiate a session with the Keycloak server and will return a OpenID token back.\n\n```python\noid_client.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n\n##### createAdminClient\n\nThis static method should be used in order to access the master Realm in Keycloak.\n\n```python\n oidc = OpenID.createAdminClient(self.USER, self.PASSWORD)\n oidc.getToken() #glTeDLlmmpLYoAAUMcFQqNOMjw5dA\n```\n### Keycloak\n\nThis class builds all the Keycloak configuration REST resources by using REST conventions we can target the majority of Keycloak services.\n\n#### Constructor\n\n```Python\nkc = Keycloak(token, self.ENDPOINT)\n```\n\nThe constructor takes two parameters:\n\n- **token**: A token with enough priviledge to perform the desired operation.\n- **endpoint**: A Keycloak or RHSSO URL endpoint, something like: ``https://my_keycloak.com``. \n\n\n#### Methods\n\n#### build\nThis methods build a REST client (capabilities detailed below) targeting a specific Keycloak REST resource.\n\n```python\ngroups = kc.build(\'groups\', \'my_realm\')\n\n# Create a group called DC\nstate = groups.create({"name": "DC"}).isOk()\n\n```\n> In this example we build the \'groups\' API for ``my_realm`` Realm.\n\n##### Supported Resources\n\nHere is a quick list of supported resources:\n\n- **users**: [users API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_user).\n- **clients**: [client API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_client). \n- **groups**: [groups API](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n- **roles**: [roles API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_create_a_new_role_for_the_realm_or_client_2)\n- **identity-provider**: [identity provider API](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_get_identity_providers)\n\n\n> As long as you find a REST endpoint that follow the standard you can use this method to build a client around it, an example of this is the non well documented ``components`` endpoint.\n\n- **components**: This API allows you configure things like [user federation](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/user-storage-federation) or [Realm keys](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.2/html/server_administration_guide/admin_permissions#realm_keys).\n\n- **authentication**: Provide access to built-in and/or custom authentication flows.\n
\n\n#### admin\nSimilar to the ``build`` method but the client points to the ``master`` realm, allowing us operation such as realm creation.\n\n```python\n main_realm = kc.admin()\n\n # Creates a realm called my_realm\n main_realm.create({"enabled": "true", "id": my_realm, "realm": my_realm})\n```\n\n\n### REST API\n\nWhen you use the ``build`` or ``admin`` methods you will get back a **REST** class pointing to the Keycloak resource, keep in mind that this class don\'t check that the resource is valid, this is done to keep it flexible and to make it easy to adapt to new Keycloak REST API changes in the future. \n\n#### Usage\n\nIn order to create one you need to ``build`` method we have used before:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nstate = users.create(batman).isOk()\n```\n\n#### Methods\n\nFollowing the example above lets see the methods we have starting with the usual CRUD methods:\n\n#### create\n\nThis method ``POST`` a dictionary into any given resource:\n\n```python\nbatman = {\n "enabled":\'true\',\n "attributes":{},\n "username":"batman",\n "firstName":"Bruce",\n "lastName":"Wayne",\n "emailVerified":""\n}\n\nstate = users.create(batman).isOk()\n```\n\n- **dictionary**: Dictionary with the fields we want to POST to the server.\n\n\n\n\n#### update\n\nThis method performs a ``PUT`` on the resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.update(id, batman_update).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n#### remove\nThis method sends a ``DELETE`` to the pointed resource.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nstate = users.remove(id).isOk()\n```\n- **id**: Id of the resource in Keycloak.\n- **dictionary**: Dictionary representing the updated fields. \n\n\n#### get\nSend a ``GET`` request to retrieve a specific Keycloak resource.\n\n```python\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nuser = users.get(id).response()\n```\n\n#### all\n\nReturn all objects of a particular resource type.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\n# Create a user called batman in DC\nuser_list = users.all() #\xa0[ {id:\'xxx-yyy\', username: \'batman\', ...} ] \n```\n#### findFirst\nFinds a resource by passing an arbitrary key/value pair.\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.findFirst({"key":"username", "value": \'batman\'})\n```\n\n#### exist\nCheck if a resource matching the provided ``id`` exists:\n```Python\nusers = kc.build(\'users\', \'DC\')\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\nusers.exists(id) #True\n```\n\n#### existByKV\nCheck if a resource matching the provided key/value pair, exists.\n\n\n```Python\nusers = kc.build(\'users\', \'DC\')\n\nusers.existByKV("username", \'batman\') #False\n```\n\n\n### ResponseHandler\n\nEach **CRUD** method returns a ``ResponseHandler`` class with the following methods.\n\n#### Methods\n\n\n#### response\nreturns the requests [response object](https://docs.python-requests.org/en/latest/api/#requests.Response).\n\n```Python\nusers.update(id, batman_update).response().status_code #HTTP 201\n```\n\n\n#### isOk\n\nReturn ``True`` if the request complete successfully otherwise it will raise an exception.\n\n```Python\nstate = users.update(id, batman_update).isOk() # Return True here.\n```\n\n#### verify\n\nDoes the same as ``isOk`` but it allow you to chain more methods.\n\n```python\nbatman_update = {\n "firstName":"Bruno",\n "emailVerified": True\n}\n\nid = \'bf81a9d9-811f-4807-bd69-3d74eecbe9f4\'\n\ncookies = users.update(id, batman_update).verify().response().cookies # Get cookies.\n```\n\n\n## Specialisations\n\n### Realms \n\n### KeycloakCaches \n\nThis class handles the Keycloak caches. \n\n#### Instantiation \n\n```python\n# Creates a REST API instance target the Realms API. \nrealms = kc.build(\'realms\', \'my_realm\') \n\n# Gets the cache Realms cache API. \ncaches = realms.caches(self.REALM)\n```\n\n#### clearUserCache \nThis method tells Keycloak to clear the user cache.\n\n```python\ncaches.clearUserCache()\n```\n\n\n#### clearRealmCache \nThis method tells Keycloak to clear the realm cache.\n\n```python\ncaches.clearRealmCache()\n```\n\n\n#### clearKeyCache \nThis method tells Keycloak to clear the external public key cache for clients and identity providers.\n\n```python\ncaches.clearKeyCache()\n```\n\n> For more information on how this caches works follow this [link](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_installation_and_configuration_guide/server_cache_configuration).\n\n\n### Users\n\n#### updateCredentials\n\nUpdate user credentials.\n\n```js\nuser_credentials = {\n \'temporary\': False,\n \'value\':\'12345\'\n}\n\nstate = users.updateCredentials(user_info, user_credentials).isOk() # Updated user password.\n```\nWhere:\n- **temporary**: Boolean where if ``True`` provide a temporary password just for the first login. \n- **value**: String with the password.\n\n\n#### joinGroup\n\nAdd a user into a existing [group](https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.0/html/server_administration_guide/groups).\n\nFirst we need a group:\n```python\ndef createDCGroup():\n group = kc.build(\'groups\', \'heroes\')\n return group.create({"name": "DC"}).isOk()\n```\n\nThen we can join the group the following way:\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\n> The API works by matching the first occurrence between the provided ``key/value`` for the two resources (User and Group), this can help in various situation for example if we want to target the user by ``uuid``.\n\n\nUsing ``uuid`` as user identifier.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "name", "value": "DC"}\n\n users.joinGroup(user, group).isOk()\n```\n\nOr we want to use the group ``id``:\n\n```python\n user = {"key": "uuid", "value": "23e4567-e89b-..."}\n group = {"key": "id", "value": "f8d91722-a1f0-45e..."}\n\n users.joinGroup(user, group).isOk()\n```\n> If the field criteria don\'t return a unique value, the first entry in the list will be used.\n#### leaveGroup\n\nRemove a user from a group.\n\n```python\n createDCGroup()\n\n users = kc.build(\'users\', \'heroes\')\n user = {"key": "username", "value": "batman"}\n group = {"key": "uuid", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n user = {"key": "uuid", "value": "12d3-a456-4"}\n group = {"key": "id", "value": "123e4567-e89b-..."}\n\n users.leaveGroup(user, group).isOk()\n\n```\n\n> The same rules for ``key/value`` discussed above also applies here.\n\n\n### Groups\n\nTo manage the relationship between realm level [roles](keycloak.org/docs/latest/server_admin/#assigning-permissions-and-access-using-roles-and-groups) and groups, we can use the **RealmsRolesMapping**.\n\nTo get an instance of this class you need to instantiate the ``group`` resource class:\n\n```Python\ngroups = kc.build(\'groups\', \'heroes\')\n```\n\nAnd use the method ``realmRoles`` passing a valid [group dictionary](https://access.redhat.com/webassets/avalon/d/red-hat-single-sign-on/version-7.0.0/restapi/#_grouprepresentation):\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n```\n\nThen we get a class with following methods:\n\n#### add\n\nAdd a list of existing roles to a group.\n\n```python\ndef makeRoles(self):\n roles = kc.build(\'roles\', self.realm)\n lvl1 = roles.create({"name": "level-1"}).isOk()\n lvl2 = roles.create({"name": "level-2"}).isOk()\n return lvl1 and lvl2\n\n\nif makeRoles():\n realmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\n realmsRoles.add(["level-1", "level-2"])\n```\n\n#### remove\nRemove a list of associated roles from a group.\n\n```python\nrealmsRoles = groups.realmRoles({"key":"name", "value":\'DC\'})\nrealmsRoles.remove(["level-1", "level-2"])\n```\n\n\n## Roles \n\n\n#### composite\nIn Keycloak we can map roles to other roles, this method allow you to do just that. \n\n```python\nrole_watch = self.kc.build(\'roles\', \'my-realm\').find(\'watch\')\nadded = role_watch.add_composite(\'view\')\n```'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'readme' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'readme' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'license' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `license = 'MIT'` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'license' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'license' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) /usr/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py:103: _WouldIgnoreField: 'dependencies' defined outside of `pyproject.toml` would be ignored. !! ########################################################################## # configuration would be ignored/result in error due to `pyproject.toml` # ########################################################################## The following seems to be defined outside of `pyproject.toml`: `dependencies = ['requests']` According to the spec (see the link below), however, setuptools CANNOT consider this value unless 'dependencies' is listed as `dynamic`. https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ For the time being, `setuptools` will still consider the given value (as a **transitional** measure), but please note that future releases of setuptools will follow strictly the standard. To prevent this warning, you can list 'dependencies' under `dynamic` or alternatively remove the `[project]` table from your file and rely entirely on other means of configuration. !! warnings.warn(msg, _WouldIgnoreField) running bdist_wheel running build running build_py creating build creating build/lib creating build/lib/kcapi copying kcapi/sso.py -> build/lib/kcapi copying kcapi/oid.py -> build/lib/kcapi copying kcapi/__init__.py -> build/lib/kcapi creating build/lib/kcapi/rest copying kcapi/rest/users.py -> build/lib/kcapi/rest copying kcapi/rest/url.py -> build/lib/kcapi/rest copying kcapi/rest/targets.py -> build/lib/kcapi/rest copying kcapi/rest/roles.py -> build/lib/kcapi/rest copying kcapi/rest/resp.py -> build/lib/kcapi/rest copying kcapi/rest/recovery.py -> build/lib/kcapi/rest copying kcapi/rest/realms.py -> build/lib/kcapi/rest copying kcapi/rest/idp.py -> build/lib/kcapi/rest copying kcapi/rest/helper.py -> build/lib/kcapi/rest copying kcapi/rest/groups.py -> build/lib/kcapi/rest copying kcapi/rest/crud.py -> build/lib/kcapi/rest copying kcapi/rest/clients.py -> build/lib/kcapi/rest copying kcapi/rest/client_scopes.py -> build/lib/kcapi/rest copying kcapi/rest/auth_flows.py -> build/lib/kcapi/rest copying kcapi/rest/__init__.py -> build/lib/kcapi/rest creating build/lib/kcapi/ie copying kcapi/ie/flows_publisher.py -> build/lib/kcapi/ie copying kcapi/ie/auth_flows.py -> build/lib/kcapi/ie copying kcapi/ie/__init__.py -> build/lib/kcapi/ie installing to build/bdist.linux-x86_64/wheel running install running install_lib creating build/bdist.linux-x86_64 creating build/bdist.linux-x86_64/wheel creating build/bdist.linux-x86_64/wheel/kcapi creating build/bdist.linux-x86_64/wheel/kcapi/ie copying build/lib/kcapi/ie/__init__.py -> build/bdist.linux-x86_64/wheel/kcapi/ie copying build/lib/kcapi/ie/auth_flows.py -> build/bdist.linux-x86_64/wheel/kcapi/ie copying build/lib/kcapi/ie/flows_publisher.py -> build/bdist.linux-x86_64/wheel/kcapi/ie creating build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/__init__.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/auth_flows.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/client_scopes.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/clients.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/crud.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/groups.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/helper.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/idp.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/realms.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/recovery.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/resp.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/roles.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/targets.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/url.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/rest/users.py -> build/bdist.linux-x86_64/wheel/kcapi/rest copying build/lib/kcapi/__init__.py -> build/bdist.linux-x86_64/wheel/kcapi copying build/lib/kcapi/oid.py -> build/bdist.linux-x86_64/wheel/kcapi copying build/lib/kcapi/sso.py -> build/bdist.linux-x86_64/wheel/kcapi running install_egg_info running egg_info writing kcapi.egg-info/PKG-INFO writing dependency_links to kcapi.egg-info/dependency_links.txt writing requirements to kcapi.egg-info/requires.txt writing top-level names to kcapi.egg-info/top_level.txt reading manifest file 'kcapi.egg-info/SOURCES.txt' adding license file 'LICENSE' writing manifest file 'kcapi.egg-info/SOURCES.txt' Copying kcapi.egg-info to build/bdist.linux-x86_64/wheel/kcapi-1.1.2-py3.11.egg-info running install_scripts creating build/bdist.linux-x86_64/wheel/kcapi-1.1.2.dist-info/WHEEL creating '/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir/pip-wheel-uzl4_4uj/.tmp-0aydch7_/kcapi-1.1.2-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it adding 'kcapi/__init__.py' adding 'kcapi/oid.py' adding 'kcapi/sso.py' adding 'kcapi/ie/__init__.py' adding 'kcapi/ie/auth_flows.py' adding 'kcapi/ie/flows_publisher.py' adding 'kcapi/rest/__init__.py' adding 'kcapi/rest/auth_flows.py' adding 'kcapi/rest/client_scopes.py' adding 'kcapi/rest/clients.py' adding 'kcapi/rest/crud.py' adding 'kcapi/rest/groups.py' adding 'kcapi/rest/helper.py' adding 'kcapi/rest/idp.py' adding 'kcapi/rest/realms.py' adding 'kcapi/rest/recovery.py' adding 'kcapi/rest/resp.py' adding 'kcapi/rest/roles.py' adding 'kcapi/rest/targets.py' adding 'kcapi/rest/url.py' adding 'kcapi/rest/users.py' adding 'kcapi-1.1.2.dist-info/LICENSE' adding 'kcapi-1.1.2.dist-info/METADATA' adding 'kcapi-1.1.2.dist-info/WHEEL' adding 'kcapi-1.1.2.dist-info/top_level.txt' adding 'kcapi-1.1.2.dist-info/RECORD' removing build/bdist.linux-x86_64/wheel Building wheel for kcapi (pyproject.toml): finished with status 'done' Created wheel for kcapi: filename=kcapi-1.1.2-py3-none-any.whl size=22278 sha256=bc4f542a5d3f72e1d5d213c9bed8d4f9af92581f62a59619116b724eec69d5ab Stored in directory: /builddir/.cache/pip/wheels/c5/34/34/0927c47f1d3bf3ec2d016dabef2719a43965021d641a228bb1 Successfully built kcapi + RPM_EC=0 ++ jobs -p + exit 0 Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.g8xGSh + umask 022 + cd /builddir/build/BUILD + '[' /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64 '!=' / ']' + rm -rf /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64 ++ dirname /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64 + mkdir -p /builddir/build/BUILDROOT + mkdir /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64 + 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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -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 kcapi-1.1.2 ++ ls /builddir/build/BUILD/kcapi-1.1.2/pyproject-wheeldir/kcapi-1.1.2-py3-none-any.whl ++ xargs basename --multiple ++ sed -E 's/([^-]+)-([^-]+)-.+\.whl/\1==\2/' + specifier=kcapi==1.1.2 + TMPDIR=/builddir/build/BUILD/kcapi-1.1.2/.pyproject-builddir + /usr/bin/python3 -m pip install --root /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64 --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/kcapi-1.1.2/pyproject-wheeldir kcapi==1.1.2 Using pip 23.0.1 from /usr/lib/python3.11/site-packages/pip (python 3.11) Looking in links: /builddir/build/BUILD/kcapi-1.1.2/pyproject-wheeldir Processing ./pyproject-wheeldir/kcapi-1.1.2-py3-none-any.whl Installing collected packages: kcapi Successfully installed kcapi-1.1.2 + '[' -d /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/bin ']' + rm -f /builddir/build/BUILD/python-kcapi-1.1.2-1.fc39.x86_64-pyproject-ghost-distinfo + site_dirs=() + '[' -d /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages ']' + site_dirs+=("/usr/lib/python3.11/site-packages") + '[' /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib64/python3.11/site-packages '!=' /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages ']' + '[' -d /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib64/python3.11/site-packages ']' + for site_dir in ${site_dirs[@]} + for distinfo in /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64$site_dir/*.dist-info + echo '%ghost /usr/lib/python3.11/site-packages/kcapi-1.1.2.dist-info' + sed -i s/pip/rpm/ /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages/kcapi-1.1.2.dist-info/INSTALLER + PYTHONPATH=/usr/lib/rpm/redhat + /usr/bin/python3 -B /usr/lib/rpm/redhat/pyproject_preprocess_record.py --buildroot /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64 --record /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages/kcapi-1.1.2.dist-info/RECORD --output /builddir/build/BUILD/python-kcapi-1.1.2-1.fc39.x86_64-pyproject-record + rm -fv /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages/kcapi-1.1.2.dist-info/RECORD removed '/builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages/kcapi-1.1.2.dist-info/RECORD' + rm -fv /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages/kcapi-1.1.2.dist-info/REQUESTED removed '/builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages/kcapi-1.1.2.dist-info/REQUESTED' ++ wc -l /builddir/build/BUILD/python-kcapi-1.1.2-1.fc39.x86_64-pyproject-ghost-distinfo ++ cut -f1 '-d ' + lines=1 + '[' 1 -ne 1 ']' + /usr/bin/python3 /usr/lib/rpm/redhat/pyproject_save_files.py --output-files /builddir/build/BUILD/python-kcapi-1.1.2-1.fc39.x86_64-pyproject-files --output-modules /builddir/build/BUILD/python-kcapi-1.1.2-1.fc39.x86_64-pyproject-modules --buildroot /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64 --sitelib /usr/lib/python3.11/site-packages --sitearch /usr/lib64/python3.11/site-packages --python-version 3.11 --pyproject-record /builddir/build/BUILD/python-kcapi-1.1.2-1.fc39.x86_64-pyproject-record --prefix /usr '*' +auto + /usr/bin/find-debuginfo -j2 --strict-build-id -m -i --build-id-seed 1.1.2-1.fc39 --unique-debug-suffix -1.1.2-1.fc39.x86_64 --unique-debug-src-base python-kcapi-1.1.2-1.fc39.x86_64 --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 -S debugsourcefiles.list /builddir/build/BUILD/kcapi-1.1.2 find: 'debug': No such file or directory + /usr/lib/rpm/check-buildroot + /usr/lib/rpm/redhat/brp-ldconfig + /usr/lib/rpm/brp-compress + /usr/lib/rpm/redhat/brp-strip-lto /usr/bin/strip + /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip + /usr/lib/rpm/check-rpaths + /usr/lib/rpm/redhat/brp-mangle-shebangs + /usr/lib/rpm/brp-remove-la-files + env /usr/lib/rpm/redhat/brp-python-bytecompile '' 1 0 -j2 Bytecompiling .py files below /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11 using python3.11 + /usr/lib/rpm/redhat/brp-python-hardlink Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.Cc3MlD + umask 022 + cd /builddir/build/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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -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 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-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 -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now -Clink-arg=-specs=/usr/lib/rpm/redhat/redhat-package-notes --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -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 kcapi-1.1.2 + '[' '!' -f /builddir/build/BUILD/python-kcapi-1.1.2-1.fc39.x86_64-pyproject-modules ']' + PATH=/builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/bin:/builddir/.local/bin:/builddir/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin + PYTHONPATH=/builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib64/python3.11/site-packages:/builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages + _PYTHONSITE=/builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib64/python3.11/site-packages:/builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64/usr/lib/python3.11/site-packages + PYTHONDONTWRITEBYTECODE=1 + /usr/bin/python3 -sP /usr/lib/rpm/redhat/import_all_modules.py -f /builddir/build/BUILD/python-kcapi-1.1.2-1.fc39.x86_64-pyproject-modules -t Check import: kcapi + RPM_EC=0 ++ jobs -p + exit 0 Processing files: python3-kcapi-1.1.2-1.fc39.noarch Provides: python-kcapi = 1.1.2-1.fc39 python3-kcapi = 1.1.2-1.fc39 python3.11-kcapi = 1.1.2-1.fc39 python3.11dist(kcapi) = 1.1.2 python3dist(kcapi) = 1.1.2 Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PartialHardlinkSets) <= 4.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 Requires: python(abi) = 3.11 python3.11dist(requests) Checking for unpackaged file(s): /usr/lib/rpm/check-files /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64 Wrote: /builddir/build/SRPMS/python-kcapi-1.1.2-1.fc39.src.rpm Wrote: /builddir/build/RPMS/python3-kcapi-1.1.2-1.fc39.noarch.rpm Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.Rvy8C7 + umask 022 + cd /builddir/build/BUILD + cd kcapi-1.1.2 + /usr/bin/rm -rf /builddir/build/BUILDROOT/python-kcapi-1.1.2-1.fc39.x86_64 + RPM_EC=0 ++ jobs -p + exit 0 Executing(rmbuild): /bin/sh -e /var/tmp/rpm-tmp.Y03Iqk + umask 022 + cd /builddir/build/BUILD + rm -rf kcapi-1.1.2 kcapi-1.1.2.gemspec + RPM_EC=0 ++ jobs -p + exit 0 Child return code was: 0