{"id":48296315,"url":"https://github.com/univention/kelvin-rest-api-client","last_synced_at":"2026-04-04T23:35:10.098Z","repository":{"id":37467348,"uuid":"256183327","full_name":"univention/kelvin-rest-api-client","owner":"univention","description":"Python library to interact with the UCS@school Kelvin REST API.","archived":false,"fork":false,"pushed_at":"2026-03-27T14:37:52.000Z","size":480,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-03-28T00:32:27.832Z","etag":null,"topics":["api-client","httpx","python","rest-client","ucs","univention","univention-corporate-server"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/univention.png","metadata":{"files":{"readme":"README.rst","changelog":"HISTORY.rst","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-04-16T10:33:08.000Z","updated_at":"2025-09-10T09:14:39.000Z","dependencies_parsed_at":"2024-01-19T15:01:23.440Z","dependency_job_id":"653d62e5-f6b9-4634-a1ca-d6d27e700016","html_url":"https://github.com/univention/kelvin-rest-api-client","commit_stats":{"total_commits":148,"total_committers":8,"mean_commits":18.5,"dds":0.6148648648648649,"last_synced_commit":"c3afcadc38eea08f3a247e3fa4efd064d5802624"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/univention/kelvin-rest-api-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/univention%2Fkelvin-rest-api-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/univention%2Fkelvin-rest-api-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/univention%2Fkelvin-rest-api-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/univention%2Fkelvin-rest-api-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/univention","download_url":"https://codeload.github.com/univention/kelvin-rest-api-client/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/univention%2Fkelvin-rest-api-client/sbom","scorecard":{"id":910394,"data":{"date":"2025-08-18","repo":{"name":"github.com/univention/kelvin-rest-api-client","commit":"5dfc91d22ebdd929374cd3f9c670a7ef7a0a2f96"},"scorecard":{"version":"v5.2.1-41-g40576783","commit":"40576783fda6698350fcbbeaea760ff827433034"},"score":2.6,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#packaging"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":7,"reason":"3 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2017-24 / GHSA-r9jw-mwhq-wp62","Warn: Project is vulnerable to: PYSEC-2022-202","Warn: Project is vulnerable to: PYSEC-2022-43017 / GHSA-qwmp-2cf2-g9g6"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/40576783fda6698350fcbbeaea760ff827433034/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T18:54:11.653Z","repository_id":37467348,"created_at":"2025-08-24T18:54:11.653Z","updated_at":"2025-08-24T18:54:11.653Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31419537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T20:09:54.854Z","status":"ssl_error","status_checked_at":"2026-04-04T20:09:44.350Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","httpx","python","rest-client","ucs","univention","univention-corporate-server"],"created_at":"2026-04-04T23:35:09.447Z","updated_at":"2026-04-04T23:35:10.086Z","avatar_url":"https://github.com/univention.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"=========================================\nPython UCS\\@school Kelvin REST API Client\n=========================================\n\n|python| |license| |ruff| |docspassing|\n\nPython library to interact with the `UCS\\@school Kelvin REST API`_.\n\n* Free software: GNU Affero General Public License version 3\n* Documentation: https://kelvin-rest-api-client.readthedocs.io\n\n\nFeatures\n--------\n\n* Asynchronous\n* Automatic handling of HTTP(S) sessions\n* Type annotations\n* ~95% test coverage (unittests + integration tests)\n* Python 3.7, 3.8, 3.9, 3.10\n\nCompatibility\n-------------\n\nA list of UCS\\@school Kelvin REST API server versions which introduce breaking changes can be found in the `UCS\\@school Kelvin REST API Documentation \u003chttps://docs.software-univention.de/ucsschool-kelvin-rest-api/kelvin-client-compatibility.html\u003e`_.\n\n\nUsage\n-----\n\nThe ``Session`` context manager opens and closes a HTTP session:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e import asyncio\n    \u003e\u003e\u003e from ucsschool.kelvin.client import Session, User, UserResource\n    \u003e\u003e\u003e\n    \u003e\u003e\u003e async def get_user(username: str) -\u003e User:\n    ...     async with Session(\n    ...         \"USERNAME\",\n    ...         \"PASSWORD\",\n    ...         \"master.ucs.local\",\n    ...         verify=\"ucs-root-ca.crt\"\n    ...     ) as session:\n    ...         return await UserResource(session=session).get(name=username)\n    ...\n    \u003e\u003e\u003e obj = asyncio.run(get_user(\"demo_student\"))\n    \u003e\u003e\u003e\n    \u003e\u003e\u003e print(obj)\n    User('name'='test_user', dn='uid=test_user,cn=schueler,cn=users,ou=DEMOSCHOOL,dc=example,dc=com')\n    \u003e\u003e\u003e print(obj.firstname, obj.lastname)\n    Test User\n\nThere are more examples in the `docs`_ *usage* section.\n\nFor HTTPS to work, the SSL CA of the target system (UCS Master) must either be publicly signed, installed on the client system or available as file (as in the example above).\nIf the SSL CA certificate is not available ``verify=False``.\nObviously that is *not safe*! The CA of any UCS server can always be downloaded from ``http://FQDN.OF.UCS/ucs-root-ca.crt``.\n\n\nInstallation\n------------\n\nInstall *UCS\\@school Kelvin REST API Client* via pip from `PyPI`_:\n\n.. code-block:: console\n\n    $ pip install kelvin-rest-api-client\n\n\nTests\n-----\n\nDevelopment internal tests\n==========================\n\nThe `Kelvin-client-daily \u003chttps://jenkins2022.knut.univention.de/job/UCSschool-5.0/job/Kelvin-client-daily/\u003e`_-job, an integration test for the Kelvin client, is run and daily with the newest UCS.\nThe job takes around 10 minutes to run and can be configured to run with a feature branch and a Kelvin Rest Api version of your choice.\nThis is the recommended way to run the full integration test suite.\n\nLocal Tests\n===========\n\nThere are some isolated unittests, but most tests run against a real *UCS\\@school Kelvin REST API*.\nA UCS 4.4 Docker container has been prepared for this (additionally to the Kelvin API Docker container).\nThe ``Makefile`` automates downloading and starting the Docker containers (3.2 GB GB) and running the tests.\nIt is also possible to use an existing UCS DC Master with UCS\\@school and the Kelvin API installed.\n\nInstall the dependencies for testing in your python virtual environment:\n\n.. code-block:: console\n\n    $ uv sync --extra test\n\nThe tests expect the existence of two schools (``OUs``) on the target system (the Kelvin API does not support creation of schools yet).\nThe schools are ``DEMOSCHOOL`` and ``DEMOSCHOOL2``.\nThe first one usually already exists, but trying to create it again is safe.\nTo create the schools run *on the UCS DC Master*:\n\n.. code-block:: console\n\n    $ /usr/share/ucs-school-import/scripts/create_ou DEMOSCHOOL\n    $ /usr/share/ucs-school-import/scripts/create_ou DEMOSCHOOL2\n\nFurthermore an email domain must exist:\n\n.. code-block:: console\n\n    $ udm mail/domain create \\\n        --ignore_exists \\\n        --position \"cn=domain,cn=mail,$(ucr get ldap/base)\" \\\n        --set name=\"$(ucr get domainname)\"\n\nSince version ``1.5.0`` the Kelvin REST API supports UDM properties in all resources. A configuration is required for the tests for this feature:\n\n.. code-block:: console\n\n    $ cat \u003e /etc/ucsschool/kelvin/mapped_udm_properties.json \u003c\u003c__EOF__\n    {\n        \"user\": [\"title\"],\n        \"school_class\": [\"mailAddress\"],\n        \"school\": [\"description\"]\n    }\n    __EOF__\n\nTo use an existing UCS server for the tests, copy the file ``tests/test_server_example.yaml`` to ``tests/test_server.yaml`` and adapt the settings before starting the tests:\n\n.. code-block:: console\n\n    $ cp tests/test_server_example.yaml tests/test_server.yaml\n    $ $EDITOR tests/test_server.yaml\n    # check settings with a single test:\n    $ uv run python -m pytest tests/test_user.py::test_get\n\nRun tests with current Python interpreter:\n\n.. code-block:: console\n\n    $ make test\n\nUsing `tox`_ the tests can be executed with all supported Python versions:\n\n.. code-block:: console\n\n    $ make test-all\n\n\nLogging\n-------\n\nStandard logging is used for tracking the libraries activity.\nTo capture the log messages for this project, subscribe to a logger named ``ucsschool.kelvin.client``.\n*Attention:* Passwords and session tokens will be logged at log level ``DEBUG``!\n\nThe *UCS\\@school Kelvin REST API* on the UCS server logs into the file ``/var/log/univention/ucsschool-kelvin-rest-api/http.log``.\nThe *UDM REST API* on the UCS server logs into the file ``/var/log/univention/directory-manager-rest.log``.\n\nRelease\n-------\n\n\n.. code-block:: markdown\n\n        - [ ] Check and update contents of [HISTORY.rst](./HISTORY.rst\u003e)\n        - [ ] Check and update contents of [VERSION.txt](./VERSION.txt\u003e)\n        - [ ] Kelvin client [Jenkins test](https://univention-dist-jenkins.k8s.knut.univention.de/job/UCSschool-5.0/view/Daily%20Tests/job/Kelvin-client-daily\u003e) OK\n        - [ ] Tag commit in gitlab\n        - [ ] Run `make dist`\n        - [ ] Run `make docs`\n        - [ ] Run `make release-test` and verify the installation\n        - [ ] Run `make release` and verify the installation\n        - [ ] Verify packages on https://pypi.org/\n        - [ ] Release mail \u0026 chat announcement\n\nRepo permissions\n----------------\n* Github: @dansan and @JuergenBS\n* Gitlab: @JuergenBS\n* PyPI: @dansan and @SamuelYaron\n* RTD: @dansan and @SamuelYaron\n\nCredits\n-------\n\n.. _`UCS\\@school Kelvin REST API`: https://docs.software-univention.de/ucsschool-kelvin-rest-api/\n.. _`tox`: http://tox.readthedocs.org/\n.. _`docs`: https://kelvin-rest-api-client.readthedocs.io\n.. _`PyPI`: https://pypi.org/project/kelvin-rest-api-client/\n.. |license| image:: https://img.shields.io/badge/License-AGPL%20v3-orange.svg\n    :alt: GNU AGPL V3 license\n    :target: https://www.gnu.org/licenses/agpl-3.0\n.. |python| image:: https://img.shields.io/badge/python-3.7+-blue.svg\n    :alt: Python 3.7+\n    :target: https://www.python.org/\n.. |docspassing| image:: https://readthedocs.org/projects/kelvin-rest-api-client/badge/?version=latest\n    :alt: Documentation Status\n    :target: https://kelvin-rest-api-client.readthedocs.io/en/latest/?badge=latest\n.. |travisci| image:: https://travis-ci.com/univention/kelvin-rest-api-client.svg?branch=master\n    :target: https://app.travis-ci.com/github/univention/kelvin-rest-api-client\n.. |ruff| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v0.json\n   :target: https://github.com/charliermarsh/ruff\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funivention%2Fkelvin-rest-api-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funivention%2Fkelvin-rest-api-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funivention%2Fkelvin-rest-api-client/lists"}