ocptv


Nameocptv JSON
Version 0.1.7 PyPI version JSON
download
home_pageNone
SummaryOCP Test & Validation project api
upload_time2024-08-21 01:28:57
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseMIT License Copyright (c) 2023 Open Compute Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords ocp ocptv specification
VCS
bugtrack_url
requirements black pytest pytest-cov mypy sphinx-autodoc-typehints sphinx-markdown-builder
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ocp-diag-python

The **OCP Test & Validation Initiative** is a collaboration between datacenter hyperscalers having the goal of standardizing aspects of the hardware validation/diagnosis space, along with providing necessary tooling to enable both diagnostic developers and executors to leverage these interfaces.

Specifically, the [ocp-diag-python](https://github.com/opencomputeproject/ocp-diag-python) project makes it easy for developers to use the **OCP Test & Validation specification** artifacts by presenting a pure-python api that can be used to output spec compliant JSON messages.

To start, please see below for [installation instructions](https://github.com/opencomputeproject/ocp-diag-python#installation) and [usage](https://github.com/opencomputeproject/ocp-diag-python#usage).

This project is part of [ocp-diag-core](https://github.com/opencomputeproject/ocp-diag-core) and exists under the same [MIT License Agreement](https://github.com/opencomputeproject/ocp-diag-python/LICENSE).

### Installation

Stable releases of the **ocp-diag-python** codebase are published to **PyPI** under the package name [ocptv](https://pypi.org/project/ocptv/), and can be easily installed with python package managers.

**Minimum python version is currently py37.**

For general usage, the following steps should be sufficient to get the latest stable version:

- **\[option 1]**: using the [Package Installer for Python](https://pypi.org/project/pip/)

    *\[optional]* if your project needs or already has a venv, activate it first, otherwise the installation will be system-wide.
    ```bash
    $ python -m venv env
    $ source env/bin/activate
    ```

    Then just install:
    ```bash
    $ pip install ocptv
    ```
- **\[option 2]** using [Python Poetry](https://python-poetry.org/)

    *\[optional]* for a completely new project, run either `poetry new` or `poetry init` (see [poetry docs](https://python-poetry.org/docs/basic-usage/#project-setup)). Then:

    ```bash
    $ poetry add ocptv
    ```

To use the bleeding edge instead of the stable version, the git repository should be cloned.
This assumes that the clone is manually kept up to date by git pulling whenever there are new commits upstream. All of the installation methods below will automatically use the latest library code.

First clone the upstream latest code:
```bash
$ git clone https://github.com/opencomputeproject/ocp-diag-python.git
$ cd ocp-diag-python
$ git checkout dev # dev branch has the latest code
```

- **\[option 1]**: using `pip` editable install

    Similar to the stable version steps above, but with `-e`. Either system-wide or inside a venv.
    ```bash
    $ pip install -e path/to/git_cloned/ocp-diag-python
    ```
- **\[option 2]**: using `poetry`

    The `--editable` flag is still in **1.2beta** as of this writing, so add the dependency to your `pyproject.toml` with `develop = true`:
    ```toml
    [tool.poetry.dependencies]
    ocptv = { path = "path/to/git_cloned/ocp-diag-python", develop = true }
    ```

    Then install everything:
    ```bash
    $ poetry install
    ```

The instructions above assume a Linux-type system. However, the steps should be identical on Windows and MacOS platforms.

See [docs.python.org](https://docs.python.org/3/library/venv.html) for more details on how to use python venvs.

### Usage

The specification does not impose any particular level of usage. To be compliant, a diagnostic package just needs output the correct artifact messages in the correct format. However, any particular such diagnostic is free to choose what aspects it needs to use/output; eg. a simple validation test may not output any measurements, opting to just have a final Diagnosis outcome.

**Full API reference is available [here](https://github.com/opencomputeproject/ocp-diag-python/blob/dev/docs/index.md).**

A very simple starter example, which just outputs a diagnosis:
```py
import ocptv.output as tv
import random

def get_fan_speed():
    return random.randrange(1500, 1700)

def main():
    run = tv.TestRun(name="simple_diagnosis", version="1.0")
    dut = tv.Dut(id="server0", name="server0.domain.net")
    with run.scope(dut=dut):
        step = run.add_step("check_fanspeed")
        with step.scope():
            if get_fan_speed() >= 1600:
                step.add_diagnosis(tv.DiagnosisType.PASS, verdict="fan_ok")
            else:
                step.add_diagnosis(tv.DiagnosisType.FAIL, verdict="fan_low")
               
if __name__ == '__main__':
    main()
```

Expected output (slightly reformatted for readability):
```json
{"schemaVersion": {"major": 2, "minor": 0}, "sequenceNumber": 0, "timestamp": "2023-04-19T20:54:05.652514+01:00"}

{"testRunArtifact": {
    "testRunStart": {
        "name": "simple_diagnosis",
        "version": "1.0", "commandLine": "", "parameters": {},
        "dutInfo": {
            "dutInfoId": "server0", "name": "server0.domain.net",
            "platformInfos": [], "softwareInfos": [], "hardwareInfos": []
        }
    }
}, "sequenceNumber": 1, "timestamp": "2023-04-19T20:54:05.652646+01:00"}

{"testStepArtifact": {
    "testStepId": "0",
    "testStepStart": { "name": "check_fanspeed" }
}, "sequenceNumber": 2, "timestamp": "2023-04-19T20:54:05.652771+01:00"}

{"testStepArtifact": {
    "testStepId": "0",
    "diagnosis": {
        "verdict": "fan_ok", "type": "PASS",
        "sourceLocation": {"file": "/home/user/ocp-diag-python/test.py", "line": 16}
    }
}, "sequenceNumber": 3, "timestamp": "2023-04-19T20:54:05.653037+01:00"}

{"testStepArtifact": {
    "testStepId": "0",
    "testStepEnd": {"status": "COMPLETE"}
}, "sequenceNumber": 4, "timestamp": "2023-04-19T20:54:05.653167+01:00"}

{"testRunArtifact": {
    "testRunEnd": {"status": "COMPLETE", "result": "PASS"}
}, "sequenceNumber": 5, "timestamp": "2023-04-19T20:54:05.653219+01:00"}
```

For more examples of usage, there are a number available in the [examples folder](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/examples), along with expected outputs.

### Configuration

There are a couple of knobs that can be used to configure the behavior of the `ocptv` library:
- **enable_runtime_checks**: when this is true, the lib code will try to validate the actual types of the data being fed to it against what the specification requires. This may be disable if performance is critical or if it shows any false positives. Default is `True`.
- **timezone**: a `datetime.tzinfo` implementation overriding the default local timezone. Default is `None`, which means local timezone.
- **writer**: a `ocptv.output.Writer` implementation that is used for the lowlevel writing of serialized JSON strings. Default is `ocptv.output.StdoutWriter` which just writes everything to standard output.

To setup any of these aspects:
```py
import ocptv.output as tv
from ocptv.output import StdoutWriter

# signature:
# config(
#     writer: ty.Optional[Writer] = None,
#     enable_runtime_checks: ty.Optional[bool] = None,
#     timezone: ty.Union[tzinfo, None] = _NOT_SET,
# )

# disable the runtime type checks
tv.config(enable_runtime_checks=False)

# change writer and timezone
tv.config(timezone=pytz.UTC, writer=StdoutWriter())
```

When using the configuration endpoint, at the moment of starting a test run, the configuration is considered committed. The settings can still be technically modified, but it might result in unexpected behavior, eg. changing the `writer` will result in a partial output, which is not compliant.

There's also some more advanced configuration in `config.py` and `advanced.py` in the [examples folder](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/examples).

### Examples

The examples in [examples folder](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/examples) are setup to run as a module.

```bash
# run all demos available
$ python -m examples

# list demo names
$ python -m examples list

# run a specific example
$ python -m examples demo_diagnosis
```

The [sample output file](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/examples/sample_output.txt) shows a run of all demos. This is meant as documentation.

### Developer notes

If you would like to contribute, please head over to [developer notes](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/DEVELOPER_NOTES.md) for instructions regarding setting up a development environment and more on submitting code.

### Contact

Feel free to start a new [discussion](https://github.com/opencomputeproject/ocp-diag-python/discussions), or otherwise post an [issue/request](https://github.com/opencomputeproject/ocp-diag-python/issues).

An email contact is also available at: ocp-test-validation@OCP-All.groups.io

<!--
due to https://github.com/pypa/readme_renderer/issues/163 we must use absolute links everywhere
-->

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "ocptv",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "ocp, ocptv, specification",
    "author": null,
    "author_email": "OCP Test & Validation <ocp-test-validation@OCP-All.groups.io>",
    "download_url": "https://files.pythonhosted.org/packages/df/93/2aa3dcd8e1656bf8da6a2319c184efb958be151b6bf57a3a91e2fb998fb5/ocptv-0.1.7.tar.gz",
    "platform": null,
    "description": "# ocp-diag-python\n\nThe **OCP Test & Validation Initiative** is a collaboration between datacenter hyperscalers having the goal of standardizing aspects of the hardware validation/diagnosis space, along with providing necessary tooling to enable both diagnostic developers and executors to leverage these interfaces.\n\nSpecifically, the [ocp-diag-python](https://github.com/opencomputeproject/ocp-diag-python) project makes it easy for developers to use the **OCP Test & Validation specification** artifacts by presenting a pure-python api that can be used to output spec compliant JSON messages.\n\nTo start, please see below for [installation instructions](https://github.com/opencomputeproject/ocp-diag-python#installation) and [usage](https://github.com/opencomputeproject/ocp-diag-python#usage).\n\nThis project is part of [ocp-diag-core](https://github.com/opencomputeproject/ocp-diag-core) and exists under the same [MIT License Agreement](https://github.com/opencomputeproject/ocp-diag-python/LICENSE).\n\n### Installation\n\nStable releases of the **ocp-diag-python** codebase are published to **PyPI** under the package name [ocptv](https://pypi.org/project/ocptv/), and can be easily installed with python package managers.\n\n**Minimum python version is currently py37.**\n\nFor general usage, the following steps should be sufficient to get the latest stable version:\n\n- **\\[option 1]**: using the [Package Installer for Python](https://pypi.org/project/pip/)\n\n    *\\[optional]* if your project needs or already has a venv, activate it first, otherwise the installation will be system-wide.\n    ```bash\n    $ python -m venv env\n    $ source env/bin/activate\n    ```\n\n    Then just install:\n    ```bash\n    $ pip install ocptv\n    ```\n- **\\[option 2]** using [Python Poetry](https://python-poetry.org/)\n\n    *\\[optional]* for a completely new project, run either `poetry new` or `poetry init` (see [poetry docs](https://python-poetry.org/docs/basic-usage/#project-setup)). Then:\n\n    ```bash\n    $ poetry add ocptv\n    ```\n\nTo use the bleeding edge instead of the stable version, the git repository should be cloned.\nThis assumes that the clone is manually kept up to date by git pulling whenever there are new commits upstream. All of the installation methods below will automatically use the latest library code.\n\nFirst clone the upstream latest code:\n```bash\n$ git clone https://github.com/opencomputeproject/ocp-diag-python.git\n$ cd ocp-diag-python\n$ git checkout dev # dev branch has the latest code\n```\n\n- **\\[option 1]**: using `pip` editable install\n\n    Similar to the stable version steps above, but with `-e`. Either system-wide or inside a venv.\n    ```bash\n    $ pip install -e path/to/git_cloned/ocp-diag-python\n    ```\n- **\\[option 2]**: using `poetry`\n\n    The `--editable` flag is still in **1.2beta** as of this writing, so add the dependency to your `pyproject.toml` with `develop = true`:\n    ```toml\n    [tool.poetry.dependencies]\n    ocptv = { path = \"path/to/git_cloned/ocp-diag-python\", develop = true }\n    ```\n\n    Then install everything:\n    ```bash\n    $ poetry install\n    ```\n\nThe instructions above assume a Linux-type system. However, the steps should be identical on Windows and MacOS platforms.\n\nSee [docs.python.org](https://docs.python.org/3/library/venv.html) for more details on how to use python venvs.\n\n### Usage\n\nThe specification does not impose any particular level of usage. To be compliant, a diagnostic package just needs output the correct artifact messages in the correct format. However, any particular such diagnostic is free to choose what aspects it needs to use/output; eg. a simple validation test may not output any measurements, opting to just have a final Diagnosis outcome.\n\n**Full API reference is available [here](https://github.com/opencomputeproject/ocp-diag-python/blob/dev/docs/index.md).**\n\nA very simple starter example, which just outputs a diagnosis:\n```py\nimport ocptv.output as tv\nimport random\n\ndef get_fan_speed():\n    return random.randrange(1500, 1700)\n\ndef main():\n    run = tv.TestRun(name=\"simple_diagnosis\", version=\"1.0\")\n    dut = tv.Dut(id=\"server0\", name=\"server0.domain.net\")\n    with run.scope(dut=dut):\n        step = run.add_step(\"check_fanspeed\")\n        with step.scope():\n            if get_fan_speed() >= 1600:\n                step.add_diagnosis(tv.DiagnosisType.PASS, verdict=\"fan_ok\")\n            else:\n                step.add_diagnosis(tv.DiagnosisType.FAIL, verdict=\"fan_low\")\n               \nif __name__ == '__main__':\n    main()\n```\n\nExpected output (slightly reformatted for readability):\n```json\n{\"schemaVersion\": {\"major\": 2, \"minor\": 0}, \"sequenceNumber\": 0, \"timestamp\": \"2023-04-19T20:54:05.652514+01:00\"}\n\n{\"testRunArtifact\": {\n    \"testRunStart\": {\n        \"name\": \"simple_diagnosis\",\n        \"version\": \"1.0\", \"commandLine\": \"\", \"parameters\": {},\n        \"dutInfo\": {\n            \"dutInfoId\": \"server0\", \"name\": \"server0.domain.net\",\n            \"platformInfos\": [], \"softwareInfos\": [], \"hardwareInfos\": []\n        }\n    }\n}, \"sequenceNumber\": 1, \"timestamp\": \"2023-04-19T20:54:05.652646+01:00\"}\n\n{\"testStepArtifact\": {\n    \"testStepId\": \"0\",\n    \"testStepStart\": { \"name\": \"check_fanspeed\" }\n}, \"sequenceNumber\": 2, \"timestamp\": \"2023-04-19T20:54:05.652771+01:00\"}\n\n{\"testStepArtifact\": {\n    \"testStepId\": \"0\",\n    \"diagnosis\": {\n        \"verdict\": \"fan_ok\", \"type\": \"PASS\",\n        \"sourceLocation\": {\"file\": \"/home/user/ocp-diag-python/test.py\", \"line\": 16}\n    }\n}, \"sequenceNumber\": 3, \"timestamp\": \"2023-04-19T20:54:05.653037+01:00\"}\n\n{\"testStepArtifact\": {\n    \"testStepId\": \"0\",\n    \"testStepEnd\": {\"status\": \"COMPLETE\"}\n}, \"sequenceNumber\": 4, \"timestamp\": \"2023-04-19T20:54:05.653167+01:00\"}\n\n{\"testRunArtifact\": {\n    \"testRunEnd\": {\"status\": \"COMPLETE\", \"result\": \"PASS\"}\n}, \"sequenceNumber\": 5, \"timestamp\": \"2023-04-19T20:54:05.653219+01:00\"}\n```\n\nFor more examples of usage, there are a number available in the [examples folder](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/examples), along with expected outputs.\n\n### Configuration\n\nThere are a couple of knobs that can be used to configure the behavior of the `ocptv` library:\n- **enable_runtime_checks**: when this is true, the lib code will try to validate the actual types of the data being fed to it against what the specification requires. This may be disable if performance is critical or if it shows any false positives. Default is `True`.\n- **timezone**: a `datetime.tzinfo` implementation overriding the default local timezone. Default is `None`, which means local timezone.\n- **writer**: a `ocptv.output.Writer` implementation that is used for the lowlevel writing of serialized JSON strings. Default is `ocptv.output.StdoutWriter` which just writes everything to standard output.\n\nTo setup any of these aspects:\n```py\nimport ocptv.output as tv\nfrom ocptv.output import StdoutWriter\n\n# signature:\n# config(\n#     writer: ty.Optional[Writer] = None,\n#     enable_runtime_checks: ty.Optional[bool] = None,\n#     timezone: ty.Union[tzinfo, None] = _NOT_SET,\n# )\n\n# disable the runtime type checks\ntv.config(enable_runtime_checks=False)\n\n# change writer and timezone\ntv.config(timezone=pytz.UTC, writer=StdoutWriter())\n```\n\nWhen using the configuration endpoint, at the moment of starting a test run, the configuration is considered committed. The settings can still be technically modified, but it might result in unexpected behavior, eg. changing the `writer` will result in a partial output, which is not compliant.\n\nThere's also some more advanced configuration in `config.py` and `advanced.py` in the [examples folder](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/examples).\n\n### Examples\n\nThe examples in [examples folder](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/examples) are setup to run as a module.\n\n```bash\n# run all demos available\n$ python -m examples\n\n# list demo names\n$ python -m examples list\n\n# run a specific example\n$ python -m examples demo_diagnosis\n```\n\nThe [sample output file](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/examples/sample_output.txt) shows a run of all demos. This is meant as documentation.\n\n### Developer notes\n\nIf you would like to contribute, please head over to [developer notes](https://github.com/opencomputeproject/ocp-diag-python/tree/dev/DEVELOPER_NOTES.md) for instructions regarding setting up a development environment and more on submitting code.\n\n### Contact\n\nFeel free to start a new [discussion](https://github.com/opencomputeproject/ocp-diag-python/discussions), or otherwise post an [issue/request](https://github.com/opencomputeproject/ocp-diag-python/issues).\n\nAn email contact is also available at: ocp-test-validation@OCP-All.groups.io\n\n<!--\ndue to https://github.com/pypa/readme_renderer/issues/163 we must use absolute links everywhere\n-->\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2023 Open Compute Project  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "OCP Test & Validation project api",
    "version": "0.1.7",
    "project_urls": {
        "Bug reports": "https://github.com/opencomputeproject/ocp-diag-python/issues",
        "Homepage": "https://github.com/opencomputeproject/ocp-diag-python",
        "Source": "https://github.com/opencomputeproject/ocp-diag-python"
    },
    "split_keywords": [
        "ocp",
        " ocptv",
        " specification"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e4cdeb3209b2764b49706bbac7b4fdaa85033b7fd2f0bc1fcf72b6b05b679cb4",
                "md5": "7d28d061f7a72521c91e64f780c2341a",
                "sha256": "6a0423fb9b5bee7e94455d16fccf7e8325ad280dd8b74abdef963ed35458bf3f"
            },
            "downloads": -1,
            "filename": "ocptv-0.1.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7d28d061f7a72521c91e64f780c2341a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 30329,
            "upload_time": "2024-08-21T01:28:55",
            "upload_time_iso_8601": "2024-08-21T01:28:55.811334Z",
            "url": "https://files.pythonhosted.org/packages/e4/cd/eb3209b2764b49706bbac7b4fdaa85033b7fd2f0bc1fcf72b6b05b679cb4/ocptv-0.1.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "df932aa3dcd8e1656bf8da6a2319c184efb958be151b6bf57a3a91e2fb998fb5",
                "md5": "96d7bc5ba04ccfb073055ed6b27de554",
                "sha256": "54b33d1db145302ee66bd11b8aae300fdaf73ea2ee0c49fc326cec22bb7efd99"
            },
            "downloads": -1,
            "filename": "ocptv-0.1.7.tar.gz",
            "has_sig": false,
            "md5_digest": "96d7bc5ba04ccfb073055ed6b27de554",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 54852,
            "upload_time": "2024-08-21T01:28:57",
            "upload_time_iso_8601": "2024-08-21T01:28:57.741146Z",
            "url": "https://files.pythonhosted.org/packages/df/93/2aa3dcd8e1656bf8da6a2319c184efb958be151b6bf57a3a91e2fb998fb5/ocptv-0.1.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-21 01:28:57",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "opencomputeproject",
    "github_project": "ocp-diag-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "black",
            "specs": [
                [
                    ">=",
                    "23.3"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    ">=",
                    "7.3"
                ]
            ]
        },
        {
            "name": "pytest-cov",
            "specs": [
                [
                    ">=",
                    "4.0"
                ]
            ]
        },
        {
            "name": "mypy",
            "specs": [
                [
                    ">=",
                    "1.2"
                ]
            ]
        },
        {
            "name": "sphinx-autodoc-typehints",
            "specs": [
                [
                    ">=",
                    "1.23.0"
                ]
            ]
        },
        {
            "name": "sphinx-markdown-builder",
            "specs": [
                [
                    ">=",
                    "0.5.5"
                ]
            ]
        }
    ],
    "lcname": "ocptv"
}
        
Elapsed time: 0.69650s