Name | reqif JSON |
Version |
0.0.42
JSON |
| download |
home_page | None |
Summary | Python library for ReqIF format. ReqIF parsing and unparsing. |
upload_time | 2024-04-27 15:37:42 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.7 |
license | None |
keywords |
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# ReqIF
ReqIF is a Python library for working with ReqIF format.
## Supported features
- Parsing/unparsing ReqIF
- Formatting (pretty-printing) ReqIF
- Basic validation of ReqIF
- Anonymizing ReqIF files to safely exchange the problematic ReqIF files.
## Getting started
```bash
pip install reqif
```
## Using ReqIF as a library
### Parsing ReqIF
```py
from reqif.parser import ReqIFParser
input_file_path = "input.reqif"
reqif_bundle = ReqIFParser.parse(input_file_path)
for specification in reqif_bundle.core_content.req_if_content.specifications:
print(specification.long_name)
for current_hierarchy in reqif_bundle.iterate_specification_hierarchy(specification):
print(current_hierarchy)
```
or for ReqIFz files:
```py
from reqif.parser import ReqIFZParser
input_file_path = "input.reqifz"
reqifz_bundle = ReqIFZParser.parse(input_file_path)
for reqif_bundle_file, reqif_bundle in reqifz_bundle.reqif_bundles.items():
print(f"Bundle: {reqif_bundle_file} {reqif_bundle}")
for specification in reqif_bundle.core_content.req_if_content.specifications:
print(specification)
for attachment in reqifz_bundle.attachments:
print(f"Attachment: {attachment}")
```
### Unparsing ReqIF
```py
from reqif.parser import ReqIFParser
from reqif.unparser import ReqIFUnparser
input_file_path = "input.sdoc"
output_file_path = "output.sdoc"
reqif_bundle = ReqIFParser.parse(input_file_path)
reqif_xml_output = ReqIFUnparser.unparse(reqif_bundle)
with open(output_file_path, "w", encoding="UTF-8") as output_file:
output_file.write(reqif_xml_output)
```
The contents of `reqif_xml_output` should be the same as the contents of the
`input_file`.
## Using ReqIF as a command-line tool
After installing the `reqif` Pip package, the `reqif` command becomes available
and can be executed from the command line.
```commandline
reqif
usage: reqif [-h] {passthrough,anonymize,dump,format,validate,version} ...
reqif: error: the following arguments are required: command
```
### Validate command
The `validate` command is the first command to run against a ReqIF file. The
`reqif` library contains two sets of checks:
1. reqif-internal checks of a ReqIF file's schema and semantics.
2. a check of a ReqIF file against the
[ReqIF's official schema](https://www.omg.org/spec/ReqIF/20110401/reqif.xsd)
maintained by the Object Management Group (OMG).
The first set of checks is always enabled. To enable the second set of the
official ReqIF schema checks, use `--use-reqif-schema`:
```commandline
reqif validate --use-reqif-schema sample.reqif
```
If an error is found, the `reqif validate` command exits with 1. If no errors
are found, the exit code is `0`.
### Passthrough command
The `reqif passthrough` command is a useful tool for verifying whether the reqif
tool correctly parses a given ReqIF file format that the user has at hand.
The `passthrough` command first parses the ReqIF XML into in-memory Python
objects and then unparses these Python objects back to an output ReqIF file.
If everything goes fine, the output of the passthrough command should be
identical to the contents of the input file.
`tests/integration/examples` contains samples of ReqIF files found on the
internet. The integration tests ensure that for these samples, the passthrough
command always produces outputs that are identical to inputs.
### Formatting ReqIF
The `format` command is similar to `clang-format` for C/C++ files or
`cmake-format` for CMake files. The input file is parsed and then pretty-printed
back to an output file.
This command is useful when dealing with the ReqIF files that are hand-written
or the ReqIF files produced by the ReqIF tools that do not generate well-formed
XML with consistent indentation.
The `tests/integration/commands/format` contains typical examples of
incorrectly formatted ReqIF files. The integration tests ensure that the
`format` command fixes these issues.
### Anonymizing ReqIF
The anonymization helps when exchanging ReqIF documents between different ReqIF
tools including this `reqif` library. If a particular file is not recognized
correctly by a tool, a user can send their anonymized file to a developer for
further inspection.
The anonymize command accepts an input `.reqif` file and produces an anonymized
version of that file to the output `.reqif` file.
```
usage: reqif anonymize [-h] input_file output_file
main.py anonymize: error: the following arguments are required: input_file, output_file
```
Examples of anonymization:
```xml
...
<ATTRIBUTE-VALUE-STRING THE-VALUE="...Anonymized-2644691225...">
...
<ATTRIBUTE-VALUE-XHTML>
<DEFINITION>
<ATTRIBUTE-DEFINITION-XHTML-REF>rmf-7d0ed062-e964-424c-8305-45067118d959</ATTRIBUTE-DEFINITION-XHTML-REF>
</DEFINITION>
<THE-VALUE>...Anonymized-141441514...</THE-VALUE>
...
```
The anonymization algorithm preserves the uniqueness of the anonymized strings
in the document. This way, if the requirement UID identifiers are anonymized,
they will still be unique strings in an anonymized document.
## How-to examples
The `tests/integration/examples` folder contains various examples of how the
ReqIF library can be used. Some examples could be and will be made more
advanced over time. The examples are stored in the integration tests folder, so
that they don't regress over time. The feedback and other example requests are
welcome.
## Implementation details
The core of the library is a **ReqIF first-stage parser** that only transforms
the contents of a ReqIF XML file into a ReqIF in-memory representation. The
in-memory representation is a tree of Python objects that map directly to the
objects of the ReqIF XML file structure (e.g, Spec Objects, Spec Types, Data
Types, Specifications, etc.).
### Parsing: Converting from ReqIF to other formats
The first-stage parser (implemented by the class `ReqIFParser`) can be used by
user's second-stage parser/converter scripts that convert the ReqIF in-memory
structure into a desired format such as Excel, HTML or other formats. The
two-stage process allows the first stage parsing to focus solely on creating an
in-memory ReqIF object tree, while the second stage parsing can further parse
the ReqIF object tree according to the logical structure of user's documents as
encoded in the ReqIF XML file that was produced by user's requirements
management tool.
### Unparsing: Converting from other formats to ReqIF
The reverse process is also possible. A user's script converts another format's
contents into a ReqIF in-memory representation. The ReqIF un-parser
(implemented by the class `ReqIFUnparser`) can be used to render the in-memory
objects to the ReqIF XML file.
### Tolerance
The first-stage parser is made tolerant against possible issues in ReqIF.
It should be possible to parse a ReqIF file even if it is missing important
information.
A minimum ReqIF parsed by the `reqif`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<REQ-IF xmlns="http://www.omg.org/spec/ReqIF/20110401/reqif.xsd" xmlns:configuration="http://eclipse.org/rmf/pror/toolextensions/1.0">
</REQ-IF>
```
A separate validation command shall be used to confirm the validity
of the ReqIF contents.
### Printing of the attributes
The `reqif` library uses a simple convention for printing the XML attributes: the
attributes are always printed in the alphabetic order of their attribute names.
```xml
<DATATYPE-DEFINITION-REAL ACCURACY="10" IDENTIFIER="ID_TC1000_DatatypeDefinitionReal" LAST-CHANGE="2012-04-07T01:51:37.112+02:00" LONG-NAME="TC1000 DatatypeDefinitionReal" MAX="1234.5678" MIN="-1234.5678"/>
```
Some tools do not respect this rule: for example some tools will print
the attribute `ACCURACY="10"` after the `LONG-NAME` attribute but the `reqif`
library does not provide support for preserving a non-alphabetic order of the
attributes.
### A bottom-up overview of the ReqIF format
- ReqIF is a standard. See reference document [RD01](#rd01-reqif-standard).
- ReqIF has a fixed structure (see "What is common for all ReqIF documents"
below)
- ReqIF standard does not define a document structure for every documents so
a ReqIF tool implementor is free to choose between several implementation
approaches. There is a
[ReqIF Implementation Guide](#rd02-reqif-implementation-guide)
that attempts to harmonize ReqIF tool developments. See also
"What is left open by the ReqIF standard" below.
- ReqIF files produced by various tool often have incomplete schemas.
### What is common for all ReqIF documents
- All documents have ReqIF tags:
- Document metadata is stored inside tags of `REQ-IF-HEADER` tag.
- Requirements are stored as `<SPEC-OBJECT>`s
- Requirements types are stored as `<SPEC-TYPE>`s
- Supported data types are stored as `<DATATYPE>`
- Relationships such as 'Parent-Child' as stored as `<SPEC-RELATIONS>`
### What is left open by the ReqIF standard
- How to distinguish requirements from headers/sections?
- One way: create separate `SPEC-TYPES`: one or more for requirements and
one for sections.
- Another way: have one spec type but have it provide a `TYPE` field that can
be used to distinguish between `REQUIREMENT` or `SECTION`.
- Yet another way: Check if the "ReqIF.ChapterName" is present on the spec object.
When present, it is a section. When not, it is a requirement.
## Reference documents
### [RD01] ReqIF standard
The latest version is 1.2:
[Requirements Interchange Format](https://www.omg.org/spec/ReqIF)
### [RD02] ReqIF Implementation Guide
[ReqIF Implementation Guide v1.8](https://www.prostep.org/fileadmin/downloads/prostep-ivip_ImplementationGuide_ReqIF_V1-8.pdf)
Raw data
{
"_id": null,
"home_page": null,
"name": "reqif",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": null,
"author": null,
"author_email": "Stanislav Pankevich <s.pankevich@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/ce/c0/11d2a01a66d9efe7b5b40438acf9e558ea7e866eec4c5bbd4e470b976f8a/reqif-0.0.42.tar.gz",
"platform": null,
"description": "# ReqIF\n\nReqIF is a Python library for working with ReqIF format.\n\n## Supported features\n\n- Parsing/unparsing ReqIF\n- Formatting (pretty-printing) ReqIF\n- Basic validation of ReqIF\n- Anonymizing ReqIF files to safely exchange the problematic ReqIF files.\n\n## Getting started\n\n```bash\npip install reqif\n```\n\n## Using ReqIF as a library\n\n### Parsing ReqIF\n\n```py\nfrom reqif.parser import ReqIFParser\n\ninput_file_path = \"input.reqif\"\n\nreqif_bundle = ReqIFParser.parse(input_file_path)\nfor specification in reqif_bundle.core_content.req_if_content.specifications:\n print(specification.long_name)\n\n for current_hierarchy in reqif_bundle.iterate_specification_hierarchy(specification):\n print(current_hierarchy)\n```\n\nor for ReqIFz files:\n\n```py\nfrom reqif.parser import ReqIFZParser\n\ninput_file_path = \"input.reqifz\"\n\nreqifz_bundle = ReqIFZParser.parse(input_file_path)\nfor reqif_bundle_file, reqif_bundle in reqifz_bundle.reqif_bundles.items():\n print(f\"Bundle: {reqif_bundle_file} {reqif_bundle}\")\n for specification in reqif_bundle.core_content.req_if_content.specifications:\n print(specification)\n\nfor attachment in reqifz_bundle.attachments:\n print(f\"Attachment: {attachment}\")\n```\n\n### Unparsing ReqIF\n\n```py\nfrom reqif.parser import ReqIFParser\nfrom reqif.unparser import ReqIFUnparser\n\ninput_file_path = \"input.sdoc\"\noutput_file_path = \"output.sdoc\"\n\nreqif_bundle = ReqIFParser.parse(input_file_path)\nreqif_xml_output = ReqIFUnparser.unparse(reqif_bundle)\nwith open(output_file_path, \"w\", encoding=\"UTF-8\") as output_file:\n output_file.write(reqif_xml_output)\n```\n\nThe contents of `reqif_xml_output` should be the same as the contents of the \n`input_file`.\n\n## Using ReqIF as a command-line tool\n\nAfter installing the `reqif` Pip package, the `reqif` command becomes available\nand can be executed from the command line.\n\n```commandline\nreqif\nusage: reqif [-h] {passthrough,anonymize,dump,format,validate,version} ...\nreqif: error: the following arguments are required: command\n```\n\n### Validate command\n\nThe `validate` command is the first command to run against a ReqIF file. The\n`reqif` library contains two sets of checks: \n\n1. reqif-internal checks of a ReqIF file's schema and semantics.\n2. a check of a ReqIF file against the\n [ReqIF's official schema](https://www.omg.org/spec/ReqIF/20110401/reqif.xsd)\n maintained by the Object Management Group (OMG).\n\nThe first set of checks is always enabled. To enable the second set of the \nofficial ReqIF schema checks, use `--use-reqif-schema`:\n\n```commandline\nreqif validate --use-reqif-schema sample.reqif \n```\n\nIf an error is found, the `reqif validate` command exits with 1. If no errors\nare found, the exit code is `0`.\n\n### Passthrough command\n\nThe `reqif passthrough` command is a useful tool for verifying whether the reqif\ntool correctly parses a given ReqIF file format that the user has at hand.\nThe `passthrough` command first parses the ReqIF XML into in-memory Python \nobjects and then unparses these Python objects back to an output ReqIF file.\n\nIf everything goes fine, the output of the passthrough command should be\nidentical to the contents of the input file.\n\n`tests/integration/examples` contains samples of ReqIF files found on the \ninternet. The integration tests ensure that for these samples, the passthrough\ncommand always produces outputs that are identical to inputs. \n\n### Formatting ReqIF\n\nThe `format` command is similar to `clang-format` for C/C++ files or \n`cmake-format` for CMake files. The input file is parsed and then pretty-printed\nback to an output file.\n\nThis command is useful when dealing with the ReqIF files that are hand-written\nor the ReqIF files produced by the ReqIF tools that do not generate well-formed\nXML with consistent indentation. \n\nThe `tests/integration/commands/format` contains typical examples of\nincorrectly formatted ReqIF files. The integration tests ensure that the\n`format` command fixes these issues.\n\n### Anonymizing ReqIF\n\nThe anonymization helps when exchanging ReqIF documents between different ReqIF\ntools including this `reqif` library. If a particular file is not recognized\ncorrectly by a tool, a user can send their anonymized file to a developer for\nfurther inspection.\n\nThe anonymize command accepts an input `.reqif` file and produces an anonymized\nversion of that file to the output `.reqif` file.\n\n```\nusage: reqif anonymize [-h] input_file output_file\nmain.py anonymize: error: the following arguments are required: input_file, output_file\n```\n\nExamples of anonymization:\n\n```xml\n...\n<ATTRIBUTE-VALUE-STRING THE-VALUE=\"...Anonymized-2644691225...\">\n...\n<ATTRIBUTE-VALUE-XHTML>\n <DEFINITION>\n <ATTRIBUTE-DEFINITION-XHTML-REF>rmf-7d0ed062-e964-424c-8305-45067118d959</ATTRIBUTE-DEFINITION-XHTML-REF>\n </DEFINITION>\n <THE-VALUE>...Anonymized-141441514...</THE-VALUE>\n...\n```\n\nThe anonymization algorithm preserves the uniqueness of the anonymized strings\nin the document. This way, if the requirement UID identifiers are anonymized,\nthey will still be unique strings in an anonymized document.\n\n## How-to examples\n\nThe `tests/integration/examples` folder contains various examples of how the\nReqIF library can be used. Some examples could be and will be made more\nadvanced over time. The examples are stored in the integration tests folder, so\nthat they don't regress over time. The feedback and other example requests are\nwelcome.\n\n## Implementation details\n\nThe core of the library is a **ReqIF first-stage parser** that only transforms\nthe contents of a ReqIF XML file into a ReqIF in-memory representation. The\nin-memory representation is a tree of Python objects that map directly to the \nobjects of the ReqIF XML file structure (e.g, Spec Objects, Spec Types, Data\nTypes, Specifications, etc.).\n\n### Parsing: Converting from ReqIF to other formats\n\nThe first-stage parser (implemented by the class `ReqIFParser`) can be used by\nuser's second-stage parser/converter scripts that convert the ReqIF in-memory\nstructure into a desired format such as Excel, HTML or other formats. The\ntwo-stage process allows the first stage parsing to focus solely on creating an\nin-memory ReqIF object tree, while the second stage parsing can further parse\nthe ReqIF object tree according to the logical structure of user's documents as\nencoded in the ReqIF XML file that was produced by user's requirements\nmanagement tool.\n\n### Unparsing: Converting from other formats to ReqIF\n\nThe reverse process is also possible. A user's script converts another format's\ncontents into a ReqIF in-memory representation. The ReqIF un-parser\n(implemented by the class `ReqIFUnparser`) can be used to render the in-memory\nobjects to the ReqIF XML file.\n\n### Tolerance\n\nThe first-stage parser is made tolerant against possible issues in ReqIF.\nIt should be possible to parse a ReqIF file even if it is missing important\ninformation.\n\nA minimum ReqIF parsed by the `reqif`:\n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<REQ-IF xmlns=\"http://www.omg.org/spec/ReqIF/20110401/reqif.xsd\" xmlns:configuration=\"http://eclipse.org/rmf/pror/toolextensions/1.0\">\n</REQ-IF>\n```\n\nA separate validation command shall be used to confirm the validity\nof the ReqIF contents.\n\n### Printing of the attributes\n\nThe `reqif` library uses a simple convention for printing the XML attributes: the\nattributes are always printed in the alphabetic order of their attribute names.\n\n```xml\n<DATATYPE-DEFINITION-REAL ACCURACY=\"10\" IDENTIFIER=\"ID_TC1000_DatatypeDefinitionReal\" LAST-CHANGE=\"2012-04-07T01:51:37.112+02:00\" LONG-NAME=\"TC1000 DatatypeDefinitionReal\" MAX=\"1234.5678\" MIN=\"-1234.5678\"/>\n```\n\nSome tools do not respect this rule: for example some tools will print\nthe attribute `ACCURACY=\"10\"` after the `LONG-NAME` attribute but the `reqif`\nlibrary does not provide support for preserving a non-alphabetic order of the\nattributes.\n\n### A bottom-up overview of the ReqIF format\n\n- ReqIF is a standard. See reference document [RD01](#rd01-reqif-standard).\n- ReqIF has a fixed structure (see \"What is common for all ReqIF documents\" \nbelow)\n- ReqIF standard does not define a document structure for every documents so\na ReqIF tool implementor is free to choose between several implementation \napproaches. There is a\n[ReqIF Implementation Guide](#rd02-reqif-implementation-guide)\nthat attempts to harmonize ReqIF tool developments. See also\n\"What is left open by the ReqIF standard\" below.\n- ReqIF files produced by various tool often have incomplete schemas. \n\n### What is common for all ReqIF documents\n\n- All documents have ReqIF tags:\n - Document metadata is stored inside tags of `REQ-IF-HEADER` tag.\n - Requirements are stored as `<SPEC-OBJECT>`s\n - Requirements types are stored as `<SPEC-TYPE>`s\n - Supported data types are stored as `<DATATYPE>`\n - Relationships such as 'Parent-Child' as stored as `<SPEC-RELATIONS>`\n\n### What is left open by the ReqIF standard\n \n- How to distinguish requirements from headers/sections?\n - One way: create separate `SPEC-TYPES`: one or more for requirements and\n one for sections.\n - Another way: have one spec type but have it provide a `TYPE` field that can\n be used to distinguish between `REQUIREMENT` or `SECTION`.\n - Yet another way: Check if the \"ReqIF.ChapterName\" is present on the spec object.\n When present, it is a section. When not, it is a requirement.\n\n## Reference documents\n\n### [RD01] ReqIF standard\n\nThe latest version is 1.2:\n[Requirements Interchange Format](https://www.omg.org/spec/ReqIF)\n\n### [RD02] ReqIF Implementation Guide \n\n[ReqIF Implementation Guide v1.8](https://www.prostep.org/fileadmin/downloads/prostep-ivip_ImplementationGuide_ReqIF_V1-8.pdf)\n",
"bugtrack_url": null,
"license": null,
"summary": "Python library for ReqIF format. ReqIF parsing and unparsing.",
"version": "0.0.42",
"project_urls": {
"Changelog": "https://github.com/strictdoc-project/reqif/blob/main/CHANGELOG.md",
"Homepage": "https://github.com/strictdoc-project/reqif",
"Source": "https://github.com/strictdoc-project/reqif"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "cec011d2a01a66d9efe7b5b40438acf9e558ea7e866eec4c5bbd4e470b976f8a",
"md5": "13ca5edd48557210c6dfae4375ceb191",
"sha256": "9afc4201517c20eb3f4d2f0454860744d989cd13fde11216f441f7e1f2bb9ffa"
},
"downloads": -1,
"filename": "reqif-0.0.42.tar.gz",
"has_sig": false,
"md5_digest": "13ca5edd48557210c6dfae4375ceb191",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 48048,
"upload_time": "2024-04-27T15:37:42",
"upload_time_iso_8601": "2024-04-27T15:37:42.519777Z",
"url": "https://files.pythonhosted.org/packages/ce/c0/11d2a01a66d9efe7b5b40438acf9e558ea7e866eec4c5bbd4e470b976f8a/reqif-0.0.42.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-27 15:37:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "strictdoc-project",
"github_project": "reqif",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "reqif"
}