checkmk-dev-tools


Namecheckmk-dev-tools JSON
Version 0.10.2 PyPI version JSON
download
home_pageNone
SummaryCheckmk DevOps tools
upload_time2025-07-08 11:36:03
maintainerNone
docs_urlNone
authorFrans Fürst
requires_python<4.0.0,>=3.10.4
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Checkmk Development Tools

This repository includes scripts/tools for Checkmk developers.

- TBD: what should go here
- TBD: what shouldn't go here

## Installation

While you can just clone and use the tools inside of course (they're just plain Python or Bash
scripts), the intended way to use it is via `pip` or inside a virtual environment.

Install it locally using `pip`:

```sh
[<PYTHON> -m] pip[3] install [--user] [--upgrade] checkmk-dev-tools
```

## Contained tools

### General

For tools interacting with Jenkins an API key, username and URL to Jenkins has to be provided with `~/.config/jenkins_jobs/jenkins_jobs.ini` otherwise those parameters have to be specified explicitly.

This is a template of the `jenkins_jobs.ini` file

```
[jenkins]
user=carl.lama
# Get the APIKEY from the CI web UI, click top right Profile -> Configure -> Show API Key
# https://JENKINS_URL.tld/user/carl.lama/configure
password=API_KEY_NOT_YOUR_PASSWORD
url=https://JENKINS_URL.tld
query_plugins_info=False
```

### `ci-artifacts`

`ci-artifacts` is a tool for accessing and triggering (currently Jenkins only) CI job builds and
making build artifacts available locally in an efficient way (i.e. avoiding unnessessary builds by
comparing certain constraints like job parameters and time of already available builds).

Formerly it was only used to make artifacts available which is the reason for the name and some
CLI desing desicions.

#### Usage

Run `ci-artifacts --help` in general to get more details about the usage of the tool.

##### Await result

Wait for an existing and specified build to finish. Nothing is downloaded.

```sh
ci-artifacts --log-level debug \
    await-result checkmk/master/builders/build-cmk-distro-package:6066
```

The returned result is a JSON might look like

```json
{"result": "SUCCESS", "artifacts": null}
```

##### Download

Wait for an existing and specified build to finish and download the artifacts.

The destination of the artifacts can be specified with the optional argument `--out-dir` (defaults to `out`) and is relative to the base directory (`--base-dir`, defaults to current directory) used to fetch hashes of the downloaded artifacts.
The flag `--no-remove-others` can be used to keep additional files in the download directory which were not part of the download. This is like a built-in garbage collection.

```sh
ci-artifacts --log-level debug \
    download checkmk/master/builders/build-cmk-distro-package:6066 \
    --base-dir ~/my-git-projects/checkmk/master \
    --out-dir package_download \
    --no-remove-others
```

The returned result is a JSON might look like

```json
{"result": "SUCCESS", "artifacts": ["check-mk-enterprise-2.4.0-2024.10.31_0.jammy_amd64.deb"]}
```

##### Fetch

If there are no more constraints than a build has been completed successfully, `fetch` downloads a given jobs artifact, just like with `download` but for the latest build instead of a specified build number.

Pressing `CTRL+C` while the script is running will ask for confirmation, default answer is `no` and cancel the build.

```sh
ci-artifacts --log-level debug \
    fetch checkmk/master/winagt-build
```

In contrast, this is what a more detailed call might look like

```sh
ci-artifacts --log-level debug \
    fetch checkmk/master/winagt-build \
    --params EDITION=raw,DISTRO="ubuntu-22.04",CUSTOM_GIT_REF=85fa488e0a32f6ea55d8875ab9c517bdc253a8e1 \
    --params-no-check DISABLE_CACHE=false,CIPARAM_OVERRIDE_BUILD_NODE=fra001 \
    --dependency-paths agents/wnx,agents/windows,packages/cmk-agent-ctl \
    --time-constraints today \
    --base-dir ~/my-git-projects/checkmk/master \
    --out-dir package_download
```

**`--params <JOB-PARAMETERS>`**

Comma separated list of job-parameters used for identifying existing builds and
to start new ones.

**`--params-no-check <JOB-PARAMETERS>`**

Comma separated list of job-parameters used only to start a new build. These parameters are ignored during the search of an already existing build.

**`--time-constraints <SPECIFIER>`**

Check for build date constraints when looking for existing builds - currently
only `today` is taken into account.

**`--dependency-paths <PATH,..>`**

Comma separated list of relative paths to files and directories checked for
differences when looking for existing builds.

**`--omit-new-build`**

Don't start new builds, even when no matching build could be found.

**`--force-new-build`**

Don't look for existing builds, always start a new build instead.

**`--poll-sleep`**

Overwrite default poll interval checking the status of a running Jenkins job.

**`--poll-queue-sleep`**

Overwrite default poll interval checking the status of a queued Jenkins job.

##### Request

Like `fetch` but with the optional parameter `--passive` which outputs the informations needed to trigger a build instead of triggering the build.
This is helpful in pipeline scripts to keep track of issuers of a build.

```sh
ci-artifacts --log-level debug \
    request checkmk/master/winagt-build \
    --params EDITION=raw,DISTRO="ubuntu-22.04",CUSTOM_GIT_REF=85fa488e0a32f6ea55d8875ab9c517bdc253a8e1 \
    --params-no-check DISABLE_CACHE=false,CIPARAM_OVERRIDE_BUILD_NODE=fra001 \
    --time-constraints today \
    --base-dir ~/my-git-projects/checkmk/master \
    --passive
```

```json
{
    "new_build":
    {
        "path": "checkmk/master/winagt-build",
        "params":
        {
            "EDITION": "raw",
            "DISTRO": "ubuntu-22.04",
            "CUSTOM_GIT_REF": "85fa488e0a32f6ea55d8875ab9c517bdc253a8e1",
            "DISABLE_CACHE": "false",
            "CIPARAM_OVERRIDE_BUILD_NODE": "fra001"
        }
    }
}
```

Without the `--passive` flag the build is triggered if no matching one is found. If a matching build with the specified parameters was found the returned JSON might look like

```json
{
    "existing":
    {
        "path": "checkmk/master/winagt-build",
        "number": 6066,
        "url": "https://JENKINS_URL.tld/job/checkmk/job/master/job/winagt-build/6066/",
        "result": "SUCCESS",
        "new_build": false
    }
}
```

##### Validate

The `validate` subcommand is a combination of several other commands. It requests, identifies a matching of triggers a new build while waiting for the build to complete. Nothing is downloaded. It has the same parameters as `fetch`.
This subcommand can be used to trigger a remote build with custom parameters or check if an existing build with these parameters passed or not.

```sh
ci-artifacts --log-level debug \
    validate checkmk/master/winagt-build \
    --params EDITION=raw,DISTRO="ubuntu-22.04",CUSTOM_GIT_REF=85fa488e0a32f6ea55d8875ab9c517bdc253a8e1 \
    --params-no-check DISABLE_CACHE=false,CIPARAM_OVERRIDE_BUILD_NODE=fra001 \
    --time-constraints today
```

```json
{"result": "SUCCESS", "artifacts": []}
```

#### Todo

- [ ] request CI build from local changes

### `job-resource-usage`

This is a tool to parse resource usage data for single containers
based on data collected by docker-shaper.
The [ndjson](https://github.com/ndjson/ndjson-spec) formatted data files can usually be found on the build nodes at `~jenkins/.docker_shaper/container-logs`.

#### Usage

```bash
job-resource-usage --before=7d --after=14d folder/with/datafiles/
```

### `lockable-resources`

`lockable-resources` is a tool for listing, locking and unlocking [lockable resources](https://plugins.jenkins.io/lockable-resources/) of Jenkins.

#### General

Run `lockable-resources --help` in general to get more details about the usage of the tool.

#### List

The `list` argument provides a JSON output of all labels and their resources.

```sh
lockable-resources -vvv list
```

```json
{"my_label": ["resouce1", "resouce2"], "other_label": ["this", "that"]}
```

#### Reserve and unreserve

The `reserve` and the `unreserve` argument require a single or a list of labels to lock or unlock.

```sh
lockable-resources -vvv \
[--fail-already-locked] \
[reserve, unreserve] first_resource second_resource third_resource
```

With the `--fail-already-locked` flag an exception can be thrown if the resource is already locked. If this flag is not set only a warning is logged.

To lock all resources with the label `my_lock` use the following simple call

```sh
lockable-resources list | \
jq -c .my_lock[] | \
xargs -I {} lockable-resources -vvv reserve {}
```

## Development & Contribution

### Setup

For active development you need to have `poetry` and `pre-commit` installed

```sh
python3 -m pip install --upgrade --user poetry pre-commit
git clone ssh://review.lan.tribe29.com:29418/checkmk_dev_tools
cd checkmk_dev_tools
pre-commit install
# if you need a specific version of Python inside your dev environment
poetry env use ~/.pyenv/versions/3.10.4/bin/python3
poetry install
```

### Workflow

Create a new changelog snippet. If no new snippets is found on a merged change
no new release will be built and published.

If the change is based on a Jira ticket, use the Jira ticket name as snippet
name otherwise use a unique name.

```sh
poetry run \
    changelog-generator \
    create .snippets/CMK-20150.md
```

After committing the snippet a changelog can be generated locally. For CI usage
the `--in-place` flag is recommended to use as it will update the existing
changelog with the collected snippets. For local usage remember to reset the
changelog file before a second run, as the version would be updated recursively
due to the way the changelog generator is working. It extracts the latest
version from the changelog file and puts the found snippets on top.

Future changes to the changelog are ignored by

```sh
git update-index --assume-unchanged changelog.md
```

```sh
poetry run \
    changelog-generator \
    changelog changelog.md \
    --snippets=.snippets \
    --in-place \
    --version-reference="https://review.lan.tribe29.com/gitweb?p=checkmk_dev_tools.git;a=tag;h=refs/tags/"
```

Update the version of the project in all required files by calling

```sh
poetry run \
    changelog2version \
    --changelog_file changelog.md \
    --version_file cmk_dev/version.py \
    --version_file_type py \
    --additional_version_info="-rc42+$(git rev-parse HEAD)" \
    --print \
    | jq -r .info.version
```

* modify and check commits via `pre-commit run --all-files`
* after work is done locally:

  - update dependencies before/with a new release
```sh
poetry lock
```
  - build and check package locally
```sh
poetry build && \
poetry run twine check dist/* &&
python3 -m pip uninstall -y checkmk_dev_tools && \
python3 -m pip install --user dist/checkmk_dev_tools-$(grep -E "^version.?=" pyproject.toml | cut -d '"' -f 2)-py3-none-any.whl
```
  - commit, push and review the changes
```sh
git add ...
git commit -m "cmk-dev-tools: bump version, update dependencies"
```
  - test deployed packages from `test.pypi.org`. The extra index URL is required to get those dependencies from `pypi.org` which are not available from `test.pypi.org`
```sh
pip install --no-cache-dir \
    -i https://test.pypi.org/simple/ \
    --extra-index-url https://pypi.org/simple \
    checkmk-dev-tools==<VERSION_WITH_RC>
```
  - finally merge the changes and let Jenkins create the release tag and deployment

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "checkmk-dev-tools",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0.0,>=3.10.4",
    "maintainer_email": null,
    "keywords": null,
    "author": "Frans F\u00fcrst",
    "author_email": "frans.fuerst@checkmk.com",
    "download_url": "https://files.pythonhosted.org/packages/f2/b5/263751539ea9ac33847d47860702d4bcd230730c845687d9e1d602faf50f/checkmk_dev_tools-0.10.2.tar.gz",
    "platform": null,
    "description": "# Checkmk Development Tools\n\nThis repository includes scripts/tools for Checkmk developers.\n\n- TBD: what should go here\n- TBD: what shouldn't go here\n\n## Installation\n\nWhile you can just clone and use the tools inside of course (they're just plain Python or Bash\nscripts), the intended way to use it is via `pip` or inside a virtual environment.\n\nInstall it locally using `pip`:\n\n```sh\n[<PYTHON> -m] pip[3] install [--user] [--upgrade] checkmk-dev-tools\n```\n\n## Contained tools\n\n### General\n\nFor tools interacting with Jenkins an API key, username and URL to Jenkins has to be provided with `~/.config/jenkins_jobs/jenkins_jobs.ini` otherwise those parameters have to be specified explicitly.\n\nThis is a template of the `jenkins_jobs.ini` file\n\n```\n[jenkins]\nuser=carl.lama\n# Get the APIKEY from the CI web UI, click top right Profile -> Configure -> Show API Key\n# https://JENKINS_URL.tld/user/carl.lama/configure\npassword=API_KEY_NOT_YOUR_PASSWORD\nurl=https://JENKINS_URL.tld\nquery_plugins_info=False\n```\n\n### `ci-artifacts`\n\n`ci-artifacts` is a tool for accessing and triggering (currently Jenkins only) CI job builds and\nmaking build artifacts available locally in an efficient way (i.e. avoiding unnessessary builds by\ncomparing certain constraints like job parameters and time of already available builds).\n\nFormerly it was only used to make artifacts available which is the reason for the name and some\nCLI desing desicions.\n\n#### Usage\n\nRun `ci-artifacts --help` in general to get more details about the usage of the tool.\n\n##### Await result\n\nWait for an existing and specified build to finish. Nothing is downloaded.\n\n```sh\nci-artifacts --log-level debug \\\n    await-result checkmk/master/builders/build-cmk-distro-package:6066\n```\n\nThe returned result is a JSON might look like\n\n```json\n{\"result\": \"SUCCESS\", \"artifacts\": null}\n```\n\n##### Download\n\nWait for an existing and specified build to finish and download the artifacts.\n\nThe destination of the artifacts can be specified with the optional argument `--out-dir` (defaults to `out`) and is relative to the base directory (`--base-dir`, defaults to current directory) used to fetch hashes of the downloaded artifacts.\nThe flag `--no-remove-others` can be used to keep additional files in the download directory which were not part of the download. This is like a built-in garbage collection.\n\n```sh\nci-artifacts --log-level debug \\\n    download checkmk/master/builders/build-cmk-distro-package:6066 \\\n    --base-dir ~/my-git-projects/checkmk/master \\\n    --out-dir package_download \\\n    --no-remove-others\n```\n\nThe returned result is a JSON might look like\n\n```json\n{\"result\": \"SUCCESS\", \"artifacts\": [\"check-mk-enterprise-2.4.0-2024.10.31_0.jammy_amd64.deb\"]}\n```\n\n##### Fetch\n\nIf there are no more constraints than a build has been completed successfully, `fetch` downloads a given jobs artifact, just like with `download` but for the latest build instead of a specified build number.\n\nPressing `CTRL+C` while the script is running will ask for confirmation, default answer is `no` and cancel the build.\n\n```sh\nci-artifacts --log-level debug \\\n    fetch checkmk/master/winagt-build\n```\n\nIn contrast, this is what a more detailed call might look like\n\n```sh\nci-artifacts --log-level debug \\\n    fetch checkmk/master/winagt-build \\\n    --params EDITION=raw,DISTRO=\"ubuntu-22.04\",CUSTOM_GIT_REF=85fa488e0a32f6ea55d8875ab9c517bdc253a8e1 \\\n    --params-no-check DISABLE_CACHE=false,CIPARAM_OVERRIDE_BUILD_NODE=fra001 \\\n    --dependency-paths agents/wnx,agents/windows,packages/cmk-agent-ctl \\\n    --time-constraints today \\\n    --base-dir ~/my-git-projects/checkmk/master \\\n    --out-dir package_download\n```\n\n**`--params <JOB-PARAMETERS>`**\n\nComma separated list of job-parameters used for identifying existing builds and\nto start new ones.\n\n**`--params-no-check <JOB-PARAMETERS>`**\n\nComma separated list of job-parameters used only to start a new build. These parameters are ignored during the search of an already existing build.\n\n**`--time-constraints <SPECIFIER>`**\n\nCheck for build date constraints when looking for existing builds - currently\nonly `today` is taken into account.\n\n**`--dependency-paths <PATH,..>`**\n\nComma separated list of relative paths to files and directories checked for\ndifferences when looking for existing builds.\n\n**`--omit-new-build`**\n\nDon't start new builds, even when no matching build could be found.\n\n**`--force-new-build`**\n\nDon't look for existing builds, always start a new build instead.\n\n**`--poll-sleep`**\n\nOverwrite default poll interval checking the status of a running Jenkins job.\n\n**`--poll-queue-sleep`**\n\nOverwrite default poll interval checking the status of a queued Jenkins job.\n\n##### Request\n\nLike `fetch` but with the optional parameter `--passive` which outputs the informations needed to trigger a build instead of triggering the build.\nThis is helpful in pipeline scripts to keep track of issuers of a build.\n\n```sh\nci-artifacts --log-level debug \\\n    request checkmk/master/winagt-build \\\n    --params EDITION=raw,DISTRO=\"ubuntu-22.04\",CUSTOM_GIT_REF=85fa488e0a32f6ea55d8875ab9c517bdc253a8e1 \\\n    --params-no-check DISABLE_CACHE=false,CIPARAM_OVERRIDE_BUILD_NODE=fra001 \\\n    --time-constraints today \\\n    --base-dir ~/my-git-projects/checkmk/master \\\n    --passive\n```\n\n```json\n{\n    \"new_build\":\n    {\n        \"path\": \"checkmk/master/winagt-build\",\n        \"params\":\n        {\n            \"EDITION\": \"raw\",\n            \"DISTRO\": \"ubuntu-22.04\",\n            \"CUSTOM_GIT_REF\": \"85fa488e0a32f6ea55d8875ab9c517bdc253a8e1\",\n            \"DISABLE_CACHE\": \"false\",\n            \"CIPARAM_OVERRIDE_BUILD_NODE\": \"fra001\"\n        }\n    }\n}\n```\n\nWithout the `--passive` flag the build is triggered if no matching one is found. If a matching build with the specified parameters was found the returned JSON might look like\n\n```json\n{\n    \"existing\":\n    {\n        \"path\": \"checkmk/master/winagt-build\",\n        \"number\": 6066,\n        \"url\": \"https://JENKINS_URL.tld/job/checkmk/job/master/job/winagt-build/6066/\",\n        \"result\": \"SUCCESS\",\n        \"new_build\": false\n    }\n}\n```\n\n##### Validate\n\nThe `validate` subcommand is a combination of several other commands. It requests, identifies a matching of triggers a new build while waiting for the build to complete. Nothing is downloaded. It has the same parameters as `fetch`.\nThis subcommand can be used to trigger a remote build with custom parameters or check if an existing build with these parameters passed or not.\n\n```sh\nci-artifacts --log-level debug \\\n    validate checkmk/master/winagt-build \\\n    --params EDITION=raw,DISTRO=\"ubuntu-22.04\",CUSTOM_GIT_REF=85fa488e0a32f6ea55d8875ab9c517bdc253a8e1 \\\n    --params-no-check DISABLE_CACHE=false,CIPARAM_OVERRIDE_BUILD_NODE=fra001 \\\n    --time-constraints today\n```\n\n```json\n{\"result\": \"SUCCESS\", \"artifacts\": []}\n```\n\n#### Todo\n\n- [ ] request CI build from local changes\n\n### `job-resource-usage`\n\nThis is a tool to parse resource usage data for single containers\nbased on data collected by docker-shaper.\nThe [ndjson](https://github.com/ndjson/ndjson-spec) formatted data files can usually be found on the build nodes at `~jenkins/.docker_shaper/container-logs`.\n\n#### Usage\n\n```bash\njob-resource-usage --before=7d --after=14d folder/with/datafiles/\n```\n\n### `lockable-resources`\n\n`lockable-resources` is a tool for listing, locking and unlocking [lockable resources](https://plugins.jenkins.io/lockable-resources/) of Jenkins.\n\n#### General\n\nRun `lockable-resources --help` in general to get more details about the usage of the tool.\n\n#### List\n\nThe `list` argument provides a JSON output of all labels and their resources.\n\n```sh\nlockable-resources -vvv list\n```\n\n```json\n{\"my_label\": [\"resouce1\", \"resouce2\"], \"other_label\": [\"this\", \"that\"]}\n```\n\n#### Reserve and unreserve\n\nThe `reserve` and the `unreserve` argument require a single or a list of labels to lock or unlock.\n\n```sh\nlockable-resources -vvv \\\n[--fail-already-locked] \\\n[reserve, unreserve] first_resource second_resource third_resource\n```\n\nWith the `--fail-already-locked` flag an exception can be thrown if the resource is already locked. If this flag is not set only a warning is logged.\n\nTo lock all resources with the label `my_lock` use the following simple call\n\n```sh\nlockable-resources list | \\\njq -c .my_lock[] | \\\nxargs -I {} lockable-resources -vvv reserve {}\n```\n\n## Development & Contribution\n\n### Setup\n\nFor active development you need to have `poetry` and `pre-commit` installed\n\n```sh\npython3 -m pip install --upgrade --user poetry pre-commit\ngit clone ssh://review.lan.tribe29.com:29418/checkmk_dev_tools\ncd checkmk_dev_tools\npre-commit install\n# if you need a specific version of Python inside your dev environment\npoetry env use ~/.pyenv/versions/3.10.4/bin/python3\npoetry install\n```\n\n### Workflow\n\nCreate a new changelog snippet. If no new snippets is found on a merged change\nno new release will be built and published.\n\nIf the change is based on a Jira ticket, use the Jira ticket name as snippet\nname otherwise use a unique name.\n\n```sh\npoetry run \\\n    changelog-generator \\\n    create .snippets/CMK-20150.md\n```\n\nAfter committing the snippet a changelog can be generated locally. For CI usage\nthe `--in-place` flag is recommended to use as it will update the existing\nchangelog with the collected snippets. For local usage remember to reset the\nchangelog file before a second run, as the version would be updated recursively\ndue to the way the changelog generator is working. It extracts the latest\nversion from the changelog file and puts the found snippets on top.\n\nFuture changes to the changelog are ignored by\n\n```sh\ngit update-index --assume-unchanged changelog.md\n```\n\n```sh\npoetry run \\\n    changelog-generator \\\n    changelog changelog.md \\\n    --snippets=.snippets \\\n    --in-place \\\n    --version-reference=\"https://review.lan.tribe29.com/gitweb?p=checkmk_dev_tools.git;a=tag;h=refs/tags/\"\n```\n\nUpdate the version of the project in all required files by calling\n\n```sh\npoetry run \\\n    changelog2version \\\n    --changelog_file changelog.md \\\n    --version_file cmk_dev/version.py \\\n    --version_file_type py \\\n    --additional_version_info=\"-rc42+$(git rev-parse HEAD)\" \\\n    --print \\\n    | jq -r .info.version\n```\n\n* modify and check commits via `pre-commit run --all-files`\n* after work is done locally:\n\n  - update dependencies before/with a new release\n```sh\npoetry lock\n```\n  - build and check package locally\n```sh\npoetry build && \\\npoetry run twine check dist/* &&\npython3 -m pip uninstall -y checkmk_dev_tools && \\\npython3 -m pip install --user dist/checkmk_dev_tools-$(grep -E \"^version.?=\" pyproject.toml | cut -d '\"' -f 2)-py3-none-any.whl\n```\n  - commit, push and review the changes\n```sh\ngit add ...\ngit commit -m \"cmk-dev-tools: bump version, update dependencies\"\n```\n  - test deployed packages from `test.pypi.org`. The extra index URL is required to get those dependencies from `pypi.org` which are not available from `test.pypi.org`\n```sh\npip install --no-cache-dir \\\n    -i https://test.pypi.org/simple/ \\\n    --extra-index-url https://pypi.org/simple \\\n    checkmk-dev-tools==<VERSION_WITH_RC>\n```\n  - finally merge the changes and let Jenkins create the release tag and deployment\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Checkmk DevOps tools",
    "version": "0.10.2",
    "project_urls": {
        "Changelog": "https://github.com/Checkmk/checkmk-dev-tools/blob/release/0.10.2/changelog.md",
        "Repository": "https://github.com/Checkmk/checkmk-dev-tools"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8b647c0ce65fced49182dafe35f74e4ed540cdd5491a8ac4cf7afc0a9c6dfa11",
                "md5": "e7b89776af3f68968ac4e0fe99d7feb8",
                "sha256": "52477514a32c52a53ed41a9236700f2a5582960f03139a3dc79b7a465cb6e84f"
            },
            "downloads": -1,
            "filename": "checkmk_dev_tools-0.10.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e7b89776af3f68968ac4e0fe99d7feb8",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0.0,>=3.10.4",
            "size": 46839,
            "upload_time": "2025-07-08T11:36:01",
            "upload_time_iso_8601": "2025-07-08T11:36:01.559542Z",
            "url": "https://files.pythonhosted.org/packages/8b/64/7c0ce65fced49182dafe35f74e4ed540cdd5491a8ac4cf7afc0a9c6dfa11/checkmk_dev_tools-0.10.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f2b5263751539ea9ac33847d47860702d4bcd230730c845687d9e1d602faf50f",
                "md5": "b1455713e2e963a5a242859dba64502c",
                "sha256": "82150b283bc7d666e130992ddd56583318ee472158bf2c30036fa8db19a6c645"
            },
            "downloads": -1,
            "filename": "checkmk_dev_tools-0.10.2.tar.gz",
            "has_sig": false,
            "md5_digest": "b1455713e2e963a5a242859dba64502c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0.0,>=3.10.4",
            "size": 43405,
            "upload_time": "2025-07-08T11:36:03",
            "upload_time_iso_8601": "2025-07-08T11:36:03.101123Z",
            "url": "https://files.pythonhosted.org/packages/f2/b5/263751539ea9ac33847d47860702d4bcd230730c845687d9e1d602faf50f/checkmk_dev_tools-0.10.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-08 11:36:03",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Checkmk",
    "github_project": "checkmk-dev-tools",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "checkmk-dev-tools"
}
        
Elapsed time: 1.59316s